মাল্টি স্টেটমেন্ট সারণী মূল্যযুক্ত ফাংশন বনাম ইনলাইন টেবিলের মূল্যবান কার্য


198

কয়েকটি উদাহরণ দেখানোর জন্য, কেবল incase করুন:

ইনলাইন টেবিলের মূল্যবান

CREATE FUNCTION MyNS.GetUnshippedOrders()
RETURNS TABLE
AS 
RETURN SELECT a.SaleId, a.CustomerID, b.Qty
    FROM Sales.Sales a INNER JOIN Sales.SaleDetail b
        ON a.SaleId = b.SaleId
        INNER JOIN Production.Product c ON b.ProductID = c.ProductID
    WHERE a.ShipDate IS NULL
GO

একাধিক বিবৃতি সারণী মূল্যবান

CREATE FUNCTION MyNS.GetLastShipped(@CustomerID INT)
RETURNS @CustomerOrder TABLE
(SaleOrderID    INT         NOT NULL,
CustomerID      INT         NOT NULL,
OrderDate       DATETIME    NOT NULL,
OrderQty        INT         NOT NULL)
AS
BEGIN
    DECLARE @MaxDate DATETIME

    SELECT @MaxDate = MAX(OrderDate)
    FROM Sales.SalesOrderHeader
    WHERE CustomerID = @CustomerID

    INSERT @CustomerOrder
    SELECT a.SalesOrderID, a.CustomerID, a.OrderDate, b.OrderQty
    FROM Sales.SalesOrderHeader a INNER JOIN Sales.SalesOrderHeader b
        ON a.SalesOrderID = b.SalesOrderID
        INNER JOIN Production.Product c ON b.ProductID = c.ProductID
    WHERE a.OrderDate = @MaxDate
        AND a.CustomerID = @CustomerID
    RETURN
END
GO

অন্য ধরণের এক ধরণের (ইন-লাইন বা মাল্টি স্টেটমেন্ট) ব্যবহার করার কোনও সুবিধা আছে কি? যখন কিছু অন্যের চেয়ে ভাল হয় বা পার্থক্যগুলি নিখুঁত বাক্যগত হয় তখনও কি কিছু পরিস্থিতি থাকে? আমি বুঝতে পারি যে দুটি উদাহরণ ক্যোয়ারী বিভিন্ন কাজ করছে তবে আমি কি সে কারণেই তাদের লিখতে পারি এমন কোনও কারণ আছে?

তাদের সম্পর্কে পড়া এবং সুবিধাগুলি / পার্থক্যগুলি আসলে ব্যাখ্যা করা হয়নি।


এছাড়াও ইনলাইন ফাংশনের একটি বিশাল সুবিধা হ'ল আপনি রাউইড (টিআইএমএসএএমপি) কলামগুলি নির্বাচন করতে পারবেন, যখন আপনি মাল্টিস্টেটমেন্ট ফাংশনে রিটার্ন টেবিলে টাইমস্ট্যাম্প ডেটা inোকাতে পারবেন না!
আর্ট্রু

3
একটি দুর্দান্ত থ্রেড জন্য ধন্যবাদ। আমি অনেক কিছু শিখেছি। তবে, একটি বিষয় মনে রাখতে হবে যখন এমটিএসটিভিতে আইটিভি ছিল এমন কোনও ফাংশন বদলানোর সময়, প্রোফাইলার মনে করেন আপনি কোনও আইটিভি পরিবর্তন করছেন। এমএসটিভি দৃষ্টিকোণ থেকে সিন্টেক্সটি পেতে আপনি যা-ই করেন না কেন, রিকম্পাইলটি সর্বদা ব্যর্থ হয়, সাধারণত বিগিনের পরে প্রথম বিবৃতি ঘিরে। এর চারপাশের একমাত্র উপায় ছিল পুরানো ফাংশনটি ড্রপ করা এবং নতুনটিকে এমএসটিভি হিসাবে তৈরি করা।
Fandango68

উত্তর:


141

ম্যাট এর মন্তব্য গবেষণা করতে গিয়ে, আমি আমার মূল বিবৃতিটি সংশোধন করেছি। তিনি সঠিক, একটি ইনলাইন টেবিলের মূল্যবান ফাংশন (আইটিভিএফ) এবং একটি মাল্টি-স্টেটমেন্ট টেবিলের মূল্যবান ফাংশন (এমএসটিভিএফ) এর মধ্যে পারফরম্যান্সের মধ্যে পার্থক্য থাকবে এমনকি যদি তারা উভয়ই কেবল একটি নির্বাচনী বিবৃতি কার্যকর করে। এসকিউএল সার্ভার একটি আইটিভিএফকে কিছুটা এর মতো আচরণ করবেVIEWএতে এটি প্রশ্নের মধ্যে থাকা সারণীর সর্বশেষ পরিসংখ্যান ব্যবহার করে একটি কার্যনির্বাহী পরিকল্পনা গণনা করবে। একটি এমএসটিভিএফ আপনার নির্বাচিত স্টেটমেন্টের পুরো বিষয়বস্তুকে একটি টেবিলের ভেরিয়েবলের মধ্যে স্টাফ করার সমপরিমাণ এবং তারপরে এতে যোগ দেওয়ার মতো। সুতরাং, সংকলক এমএসটিভিএফের টেবিলগুলিতে কোনও টেবিলের পরিসংখ্যান ব্যবহার করতে পারে না। সুতরাং, সমস্ত জিনিস সমান হচ্ছে, (যা তারা খুব কমই হয়), আইটিভিএফ এমএসটিভিএফের চেয়ে আরও ভাল পারফর্ম করবে। আমার পরীক্ষায়, সমাপ্তির সময় পারফরম্যান্সের পার্থক্যটি একটি পরিসংখ্যানের দিক থেকে নগণ্য ছিল, এটি লক্ষণীয় ছিল।

আপনার ক্ষেত্রে, দুটি ফাংশন কার্যত সমতুল্য নয়। এমএসটিভি ফাংশনটি প্রতিবার যখন এটি বলা হয় তখন একটি অতিরিক্ত ক্যোয়ারী করে এবং সবচেয়ে গুরুত্বপূর্ণ, গ্রাহক আইডিতে ফিল্টার করে। একটি বৃহত ক্যোয়ারিতে, অপ্টিমাইজারটি অন্যান্য ধরণের যোগদানের সুবিধা নিতে সক্ষম হবেনা কারণ এতে প্রতিটি গ্রাহককে পাস করার জন্য ফাংশনটি কল করতে হবে। তবে আপনি যদি নিজের এমএসটিভি ফাংশনটি আবার লিখে থাকেন তবে:

CREATE FUNCTION MyNS.GetLastShipped()
RETURNS @CustomerOrder TABLE
    (
    SaleOrderID    INT         NOT NULL,
    CustomerID      INT         NOT NULL,
    OrderDate       DATETIME    NOT NULL,
    OrderQty        INT         NOT NULL
    )
AS
BEGIN
    INSERT @CustomerOrder
    SELECT a.SalesOrderID, a.CustomerID, a.OrderDate, b.OrderQty
    FROM Sales.SalesOrderHeader a 
        INNER JOIN Sales.SalesOrderHeader b
            ON a.SalesOrderID = b.SalesOrderID
        INNER JOIN Production.Product c 
            ON b.ProductID = c.ProductID
    WHERE a.OrderDate = (
                        Select Max(SH1.OrderDate)
                        FROM Sales.SalesOrderHeader As SH1
                        WHERE SH1.CustomerID = A.CustomerId
                        )
    RETURN
END
GO

একটি ক্যোয়ারী সালে অপটিমাইজার একবার যে ফাংশন কল এবং একটি ভাল মৃত্যুদন্ড পরিকল্পনা গড়ে তুলতে সক্ষম হবে কিন্তু এটি এখনও একটি সমতুল্য, অ-স্থিতিমাপ ITVS বা বেশী ভালো হবে না VIEW

যখন সম্ভব হয় তখন আইটিভিএফগুলি একটি এমএসটিভিএফ-এর চেয়ে বেশি পছন্দ করা উচিত কারণ আপনি টেবিলের কলামগুলি থেকে ডেটাটাইপস, নালিয়াযোগ্যতা এবং কোলেশন যেখানে আপনি এই বৈশিষ্ট্যগুলিকে মাল্টি-স্টেটমেন্ট টেবিলের মূল্যবান ফাংশন হিসাবে ঘোষণা করেন এবং গুরুত্বপূর্ণ, আপনি আইটিভিএফ থেকে আরও কার্যকর সম্পাদনের পরিকল্পনা পাবেন। আমার অভিজ্ঞতায় আমি এমন অনেকগুলি পরিস্থিতি খুঁজে পাইনি যেখানে আইটিভিএফ হ'ল ভিউয়ের চেয়ে ভাল বিকল্প ছিল তবে মাইলেজ ভিন্ন হতে পারে।

ম্যাটকে ধন্যবাদ

যোগ

যেহেতু আমি এটি সম্প্রতি প্রকাশিত হতে দেখেছি, এখানে ওয়েইন শেফিল্ড একটি দুর্দান্ত বিশ্লেষণ করেছেন যা ইনলাইন টেবিলের মূল্যবান ফাংশন এবং মাল্টি-স্টেটমেন্ট ফাংশনগুলির মধ্যে পারফরম্যান্স পার্থক্যের তুলনা করে।

তাঁর আসল ব্লগ পোস্ট।

এসকিউএল সার্ভার সেন্ট্রালে অনুলিপি করুন


40
এটি কেবল সত্য নয় - মাল্টি-স্টেটমেন্ট ফাংশনগুলি প্রায়শই একটি বিশাল পারফরম্যান্স হিট হয় কারণ তারা কোয়েরি অপটিমাইজারকে পরিসংখ্যান ব্যবহার করা বন্ধ করে দেয়। যদি প্রতিবার আমি মাল্টি-স্টেটমেন্ট ফাংশন ব্যবহার দেখেছি কার্যকর করার পরিকল্পনার খুব খারাপ পছন্দ করায় প্রতিবারের জন্য আমি যদি 1 ডলার করে থাকি (বেশিরভাগ ক্ষেত্রে এটি সাধারণত ফিরে আসা সারি গণনা 1 হিসাবে অনুমান করে) তবে আমার কাছে একটি ছোট গাড়ি কেনার যথেষ্ট পরিমাণ ছিল।
ম্যাট হুইটফিল্ড 21

আমি খুঁজে পাওয়া সবচেয়ে ভাল ব্যাখ্যাটি প্রথম উত্তরে এবং সম্পর্কিত পোস্টে রয়েছে: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / ৪১০৯১৫২/২ সম্পর্কিত কোনও নথিটি মিস করবেন না, আপনি এটি দ্রুত পড়তে পারেন, এবং এটি অত্যন্ত আকর্ষণীয়।
জোটাবি

1
এসকিউএল সার্ভার 2017 এর জন্য এই উত্তরের জন্য কোনও আপডেট থাকবে ?: youtube.com/watch?Time_continue=2&v=szTmo6rTUjM
রাল্ফ

29

অভ্যন্তরীণভাবে, এসকিউএল সার্ভার একটি ইনলাইন টেবিলের মূল্যবান ফাংশনটিকে যেমন দেখায় তেমন আচরণ করে এবং এটি কোনও সঞ্চিত পদ্ধতিতে যেমন একটি মাল্টি-স্টেটমেন্ট টেবিলের মূল্যবান ফাংশনটি করে তেমন আচরণ করে।

যখন কোনও ইনলাইন টেবিল-মূল্যযুক্ত ফাংশনটি বাইরের ক্যোয়ারির অংশ হিসাবে ব্যবহৃত হয়, তখন ক্যোয়ারী প্রসেসর ইউডিএফ সংজ্ঞাটি প্রসারিত করে এবং একটি এক্সিকিউশন প্ল্যান উত্পন্ন করে যা এই বিষয়গুলির সূচকগুলি ব্যবহার করে অন্তর্নিহিত বস্তুগুলিতে অ্যাক্সেস করে।

মাল্টি-স্টেটমেন্ট টেবিলের মূল্যবান ফাংশনটির জন্য, ফাংশনটির জন্য নিজেই একটি এক্সিকিউশন প্ল্যান তৈরি করা হয় এবং এক্সিকিউশন প্ল্যান ক্যাশে সংরক্ষণ করা হয় (একবার যখন প্রথমবার ফাংশনটি কার্যকর করা হয়ে থাকে)। যদি মাল্টি-স্টেটমেন্ট টেবিলের মূল্যবান ফাংশনগুলি বৃহত্তর প্রশ্নের অংশ হিসাবে ব্যবহৃত হয় তবে অপটিমাইজার কীভাবে ফাংশনটি ফেরত দেয় তা জানে না এবং তাই কিছু মানক অনুমানও করে - ফলস্বরূপ এটি অনুমান করে যে ফাংশনটি একটি একক সারিতে ফিরে আসবে, এবং এর ফলাফলগুলি একক সারি সহ কোনও টেবিলের বিপরীতে একটি টেবিল স্ক্যান ব্যবহার করে ফাংশনটি অ্যাক্সেস করা হবে।

মাল্টি-স্টেটমেন্ট সারণীর মূল্যবান ফাংশনগুলি খারাপভাবে সঞ্চালন করতে পারে যখন তারা প্রচুর সংখ্যক সারি ফিরিয়ে দেয় এবং বাইরের প্রশ্নের সাথে যুক্ত হন। পারফরম্যান্সের ইস্যুগুলি মূলত নীচে থাকে যে অপটিমাইজার একটি পরিকল্পনা তৈরি করে ধরে নিবে যে একক সারিতে ফিরে এসেছে, যা অগত্যা সর্বাধিক উপযুক্ত পরিকল্পনা হবে না।

থাম্বের একটি সাধারণ নিয়ম হিসাবে আমরা খুঁজে পেয়েছি যে সম্ভাব্য পারফরম্যান্স ইস্যুগুলির কারণে যেখানে সম্ভব ইনলাইন টেবিলের মূল্যবান ফাংশনগুলি মাল্টি-স্টেটমেন্টের ক্ষেত্রে (যখন ইউডিএফ একটি বাহ্যিক ক্যোয়ারির অংশ হিসাবে ব্যবহৃত হবে) ব্যবহার করতে হবে due


2
যদিও এটি কোনও সঞ্চিত পদ্ধতির অনুরূপ বহু-বিবৃতি টেবিলের মূল্যবান ফাংশনগুলিকে চিকিত্সা করতে পারে, তবে কার্যত অভিন্ন মজুত সঞ্চিত পদ্ধতিটি বড় ডেটাসেটের জন্য একটি টেবিলের মূল্যবান ফাংশনের চেয়ে অনেক দ্রুত। আমি মাল্টি স্টেটমেন্ট টেবিলের মূল্যবান ফাংশনগুলির তুলনায় সঞ্চিত প্রক্সের সাথে লেগে আছি।
কেকোয়া

6
অন্য ফলাফলগুলিতে আপনাকে এই ফলাফলগুলিতে যোগদানের প্রয়োজন না হলে।
গিলারমো গুটিরিজ

উভয় ব্যবহার করবেন না কেন? একটি সঞ্চিত সংগ্রহ যা বহু-বিবৃতি টেবিল-মূল্যযুক্ত ফাংশনের ফলাফল প্রদান করে। দুই ভুবনের সেরা.
রবিনো

13

আরও একটি পার্থক্য আছে। একটি ইনলাইন টেবিল-মূল্যযুক্ত ফাংশনটি viewোকানো, আপডেট করা এবং এ থেকে মুছে ফেলা যেতে পারে - যেমন একটি দর্শন। অনুরূপ বিধিনিষেধগুলি প্রযোজ্য - সমষ্টি ব্যবহার করে ফাংশন আপডেট করতে পারে না, গণনাকৃত কলামগুলি আপডেট করতে পারে না।


3

আপনার উদাহরণগুলি, আমি মনে করি, প্রশ্নের উত্তরটি খুব ভালভাবে দিন। প্রথম ফাংশনটি একটি সিলেক্ট হিসাবে করা যেতে পারে, এবং ইনলাইন স্টাইলটি ব্যবহার করার একটি ভাল কারণ। দ্বিতীয়টি সম্ভবত একক বিবৃতি হিসাবে করা যেতে পারে (সর্বাধিক তারিখ পাওয়ার জন্য সাব-কোয়েরি ব্যবহার করে) তবে কিছু কোডার আপনার পক্ষে যেমনটি করেছেন তেমন একাধিক বিবৃতিতে এটি পড়া সহজতর বা আরও প্রাকৃতিক বলে মনে হতে পারে। কিছু সাধারণ কার্যাবলী একটি বিবৃতিতে সম্পন্ন করতে পারে না এবং এর জন্য বহু-বিবৃতি সংস্করণ প্রয়োজন।

আমি যখনই সম্ভব সহজতম (ইনলাইন) ব্যবহার করার এবং যখন প্রয়োজন (স্পষ্টতই) মাল্টি-স্টেটমেন্টগুলি ব্যবহার করার বা ব্যক্তিগত পছন্দ / পঠনযোগ্যতা এটি অতিরিক্ত টাইপিংয়ের জন্ম দেয় তখনই আমি পরামর্শ দিই।


উত্তর করার জন্য ধন্যবাদ. সুতরাং মূলত, মাল্টি-স্টেটমেন্টটি কেবল তখনই ব্যবহার করতে হবে যখন ফাংশনটি আরও জটিল হয়ে পড়লে পড়ার স্বার্থে কোনও ইনলাইন ফাংশনে করা সম্ভব হয়? মাল্টি-স্টেটমেন্টে কোনও পারফরম্যান্স সুবিধা রয়েছে কি?
অ্যান্ড্রুসি

আমি জানি না, তবে আমি তা ভাবব না। এসকিএল সার্ভারকে আপনি যে অপটিমাইজেশনগুলি ম্যানুয়ালি বানানোর চেষ্টা করতে পারেন তা (ভেরিয়েবল, টেম্প টেবিল বা যা কিছু ব্যবহার করে) বের করার চেষ্টা করা ভাল। যদিও আপনি অবশ্যই নির্দিষ্ট ক্ষেত্রে এটি প্রমাণ / প্রমাণ করতে কিছু পারফরম্যান্স টেস্টিং করতে পারেন।
রায়

আবার অনেক ধন্যবাদ। আমার আরও সময় পেলে আমি এটি আরও খতিয়ে দেখতে পারি! :)
অ্যান্ড্রুসি


0

আমি এটি পরীক্ষা করিনি, তবে একটি মাল্টি স্টেটমেন্ট ফাংশন ফলাফল সেটকে ক্যাশে করে। অপ্টিমাইজারটি ফাংশনটি ইনলাইন করার জন্য খুব বেশি কিছু চলছে এমন ক্ষেত্রেও ঘটতে পারে। উদাহরণস্বরূপ ধরুন আপনার একটি ফাংশন রয়েছে যা আপনি "সংস্থা নম্বর" হিসাবে পাস করেন তার উপর নির্ভর করে বিভিন্ন ডাটাবেস থেকে ফলাফল দেয়। সাধারণত, আপনি ইউনিয়নের সাথে একটি ভিউ তৈরি করতে পারেন তারপরে সমস্ত সংস্থার নাম্বার দিয়ে ফিল্টার করে তবে আমি দেখতে পেলাম যে মাঝে মাঝে এসকিএল সার্ভার পুরো ইউনিয়নকে পিছনে টেনে নিয়ে যায় এবং একটি নির্বাচিতকে কল করতে যথেষ্ট স্মার্ট নয়। একটি সারণী ফাংশন উত্স চয়ন করার জন্য যুক্তি থাকতে পারে।


0

মাল্টি লাইন ফাংশনটি ব্যবহার করার জন্য আরেকটি ক্ষেত্রে হ'ল এসকিএল সার্ভারটি যেখানে ক্লজটি নীচে ঠেকানো থেকে বিরত রাখতে হবে।

উদাহরণস্বরূপ, আমার একটি টেবিলের নাম সহ একটি টেবিল রয়েছে এবং কিছু টেবিলের নাম C05_2019 এবং C12_2018 এর মতো ফর্ম্যাট করা আছে এবং সমস্ত টেবিলের একই ধরণের স্কিমা রয়েছে। আমি সেই সমস্ত ডেটা এক টেবিলের সাথে একীভূত করতে এবং 05 এবং 12 কে একটি কমপোন কলামে এবং 2018,2019 কে এক বছরের কলামে পার্স করতে চেয়েছিলাম। তবে, ACA_StupidTable এর মতো অন্যান্য টেবিল রয়েছে যা আমি কমপ্যাকো এবং কমপায়ার এক্সট্রাক্ট করতে পারি না এবং আমি চেষ্টা করলে রূপান্তর ত্রুটি পেতে পারি। সুতরাং, আমার কোয়েরিটি দুটি অংশে ছিল, একটি অভ্যন্তরীণ কোয়েরি যা কেবলমাত্র 'C_______' এর মতো ফর্ম্যাটযুক্ত টেবিলগুলিতে ফিরে এসেছিল তারপরে বহিরাগত ক্যোয়ারীটি একটি সাব-স্ট্রিং এবং ইন্ট রূপান্তর করেছিল। কমপোন হিসাবে কাস্ট (সাবস্ট্রিং (2, 2) ইনট হিসাবে) ফলাফলগুলি ফিল্টার হওয়ার আগেই এসকিএল সার্ভারটি আমার কাস্ট ফাংশনটি রাখার সিদ্ধান্ত নিয়েছে বলে সমস্ত কিছুই দেখতে দেখতে ভাল লাগে এবং তাই আমি মনকে স্ক্র্যাম্বলিং রূপান্তর ত্রুটি পেয়েছি। একটি মাল্টি স্টেটমেন্ট টেবিল ফাংশন এটি হতে বাধা দিতে পারে,


0

খুব ঘনীভূত উপায়ে হতে পারে। আইটিভিএফ (ইনলাইন টিভিএফ): আপনি যদি ডিবি ব্যক্তি হন তবে আরও কিছু ধরণের প্যারামিটারাইজড ভিউ রয়েছে, একটি সিলেক্ট স্ট্যান্ড নিন

এমটিভিএফ (মাল্টি-স্টেটমেন্ট টিভিএফ): বিকাশকারী তৈরি করে এবং একটি সারণী ভেরিয়েবল লোড করে।


-2

আপনি যদি কোনও জিজ্ঞাসা করতে চলেছেন তবে আপনি নিজের ইনলাইন টেবিলের মূল্যবান ফাংশনে যোগ দিতে পারেন:

SELECT
    a.*,b.*
    FROM AAAA a
        INNER JOIN MyNS.GetUnshippedOrders() b ON a.z=b.z

এটি সামান্য ওভারহেড ব্যয় করবে এবং সূক্ষ্মভাবে চলবে।

যদি আপনি অনুরূপ ক্যোয়ারিতে মূল্যবান আপনার মাল্টি স্টেটমেন্ট টেবিলটি ব্যবহার করার চেষ্টা করেন তবে আপনার কার্য সম্পাদনের সমস্যা থাকবে:

SELECT
    x.a,x.b,x.c,(SELECT OrderQty FROM MyNS.GetLastShipped(x.CustomerID)) AS Qty
    FROM xxxx   x

কারণ আপনি প্রতিটি সারির জন্য ফিরে আসা 1 বার ফাংশনটি সম্পাদন করবেন, ফলাফল সেটটি বড় হওয়ার সাথে সাথে এটি ধীর এবং ধীর হয়ে চলবে।


আহ, তাই আপনি বলবেন যে পারফরম্যান্সের ক্ষেত্রে ইনলাইনটি আরও ভাল?
অ্যান্ড্রুসি

1
না, তারা উভয়ই একটি টেবিল ফেরত দেয়, যা আপনি একটি কলামে একটি টেবিল রাখার চেষ্টা করার সাথে সাথে আপনার দ্বিতীয় এসকিউএলকে অবৈধ করে তোলে।
সিজকে

1
@ হ্যাঁ, আমি আপনার মন্তব্য মন্তব্যটি আপডেট করেছি updated দ্বিতীয় ফাংশনে ব্যবহৃত ফাংশনের পরামিতিগুলি এটি একটি সাব কোয়েরি হিসাবে ব্যবহৃত হতে ধার দেয়, যার ফলে খারাপ কর্মক্ষমতা দেখা দেয়।
কেএম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.