SQL सर्वर कैश एक मल्टी-स्टेटमेंट टेबल-वैल्यू फ़ंक्शन का परिणाम है?


22

एक मल्टी-स्टेटमेंट टेबल-वैल्यू फ़ंक्शन एक टेबल चर में अपना परिणाम देता है।

क्या इन परिणामों को कभी भी पुन: उपयोग किया जाता है, या फ़ंक्शन को हमेशा हर बार पूरी तरह से मूल्यांकन किया जाता है जिसे यह कहा जाता है?

जवाबों:


23

मल्टी-स्टेटमेंट टेबल-वैल्यू फ़ंक्शन (msTVF) के परिणामों को कभी भी स्टेटमेंट्स (या कनेक्शन) में कैश्ड या फिर से उपयोग नहीं किया जाता है, लेकिन ऐसे कई तरीके हैं जिनसे msTVF रिजल्ट को एक ही स्टेटमेंट के भीतर दोबारा उपयोग किया जा सकता है । उस हद तक, एक msTVF जरूरी नहीं है कि हर बार इसे कहा जाए।

उदाहरण के लिए msTVF

यह (जानबूझकर अक्षम्य) msTVF पूर्ण पंक्ति में टाइमस्टैम्प के साथ पूर्णांक की एक निर्दिष्ट श्रेणी देता है:

IF OBJECT_ID(N'dbo.IntegerRange', 'TF') IS NOT NULL
    DROP FUNCTION dbo.IntegerRange;
GO
CREATE FUNCTION dbo.IntegerRange (@From integer, @To integer)
RETURNS @T table 
(
    n integer PRIMARY KEY, 
    ts datetime DEFAULT CURRENT_TIMESTAMP
)
WITH SCHEMABINDING
AS
BEGIN
    WHILE @From <= @To
    BEGIN
        INSERT @T (n)
        VALUES (@From);

        SET @From = @From + 1;
    END;
    RETURN;
END;

स्थैतिक तालिका चर

यदि फ़ंक्शन कॉल के सभी पैरामीटर स्थिरांक (या रनटाइम स्थिरांक) हैं, तो निष्पादन योजना एक बार तालिका चर परिणाम को आबाद करेगी। योजना का शेष भाग कई बार तालिका चर तक पहुँच सकता है। तालिका चर की स्थिर प्रकृति को निष्पादन योजना से पहचाना जा सकता है। उदाहरण के लिए:

SELECT
    IR.n,
    IR.ts 
FROM dbo.IntegerRange(1, 5) AS IR
ORDER BY
    IR.n;

के समान परिणाम देता है:

सरल परिणाम

निष्पादन योजना है:

सरल निष्पादन योजना

अनुक्रम ऑपरेटर पहले टेबल वेल्यूड फंक्शन ऑपरेटर को कॉल करता है, जो टेबल वेरिएबल को पॉप्युलेट करता है (ध्यान दें कि यह ऑपरेटर कोई पंक्तियाँ नहीं लौटाता है)। अगला, अनुक्रम अपना दूसरा इनपुट कहता है, जो तालिका चर की सामग्री (इस मामले में एक क्लस्टर इंडेक्स स्कैन का उपयोग करके) लौटाता है।

योजना के 'स्थिर' तालिका चर परिणाम का उपयोग करने वाले सस्ता एक अनुक्रम के नीचे तालिका मान्य फ़ंक्शन ऑपरेटर है - योजना के शेष होने से पहले तालिका चर को एक बार पूरी तरह से आबादी की आवश्यकता होती है।

एकाधिक पहुंच

तालिका चर परिणाम को एक से अधिक बार एक्सेस करने के लिए, हम 1 से 5 तक की पंक्तियों के साथ दूसरी तालिका का उपयोग करेंगे:

IF OBJECT_ID(N'dbo.T', 'U') IS NOT NULL
    DROP TABLE dbo.T;

CREATE TABLE dbo.T (i integer NOT NULL);

INSERT dbo.T (i) 
VALUES (1), (2), (3), (4), (5);

और एक नई क्वेरी जो इस तालिका को हमारे फ़ंक्शन से जोड़ती है (यह समान रूप से लिखा जा सकता है APPLY):

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
JOIN dbo.IntegerRange(1, 5) AS IR
    ON IR.n = T.i;

परिणाम है:

परिणाम में शामिल हों

निष्पादन योजना:

योजना में शामिल हों

पहले की तरह, अनुक्रम सारणी चर msTVF परिणाम को पहले पॉप्युलेट करता है। अगला, नेस्टेड लूप्स का उपयोग प्रत्येक पंक्ति में टेबल Tसे एमएसटीवीएफ परिणाम से एक पंक्ति में शामिल होने के लिए किया जाता है । चूंकि फ़ंक्शन परिभाषा में टेबल चर पर एक उपयोगी सूचकांक शामिल था, इसलिए एक सूचकांक की तलाश की जा सकती है।

प्रमुख बिंदु यह है कि जब msTVF के पैरामीटर स्थिरांक (वैरिएबल और पैरामीटर सहित) या निष्पादन इंजन द्वारा कथन के लिए रनटाइम स्थिरांक के रूप में माना जाता है, तो योजना में msTVF तालिका चर परिणाम के लिए दो अलग-अलग ऑपरेटरों की सुविधा होगी: एक को आबाद करने के लिए तालिका; परिणामों को एक्सेस करने के लिए दूसरा, संभवतः तालिका को कई बार एक्सेस करना, और संभवतः फ़ंक्शन परिभाषा में घोषित अनुक्रमित का उपयोग करना।

सहसंबंधित पैरामीटर और गैर-स्थिर पैरामीटर

जब परस्पर संबंधित पैरामीटर (बाहरी संदर्भ) या गैर-स्थिर फ़ंक्शन मापदंडों का उपयोग किया जाता है, तो अंतर को उजागर करने के लिए, हम तालिका की सामग्री को बदल देंगे Tताकि फ़ंक्शन को बहुत अधिक काम करना हो:

TRUNCATE TABLE dbo.T;

INSERT dbo.T (i) 
VALUES (50001), (50002), (50003), (50004), (50005);

निम्न संशोधित क्वेरी अब Tफ़ंक्शन मापदंडों में से एक में तालिका के लिए एक बाहरी संदर्भ का उपयोग करती है :

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
WHERE IR.n = T.i;

इस क्वेरी को परिणाम वापस करने में लगभग 8 सेकंड लगते हैं जैसे:

परस्पर संबंधित परिणाम

कॉलम में पंक्तियों के बीच के समय के अंतर पर ध्यान दें tsWHEREखंड एक समझदारी से आकार उत्पादन के लिए अंतिम परिणाम को सीमित करता है, लेकिन अक्षम समारोह अभी भी 50,000 के करीब पंक्तियाँ (की सहसंबद्ध मूल्य के आधार पर के साथ तालिका वैरिएबल पॉप्युलेट करने के लिए कुछ समय लगता है iमेज से T)।

निष्पादन योजना है:

संबंधित निष्पादन योजना

एक अनुक्रम ऑपरेटर की कमी पर ध्यान दें। अब, एक एकल टेबल वेल्यूएड फंक्शन ऑपरेटर है जो टेबल वेरिएबल को पॉप्युलेट करता है और नेस्टेड लूप्स के प्रत्येक पुनरावृत्ति पर अपनी पंक्तियों को वापस करता है ।

स्पष्ट होने के लिए: तालिका T में सिर्फ 5 पंक्तियों के साथ, तालिका मान्यता प्राप्त फ़ंक्शन ऑपरेटर 5 बार चलता है। यह पहली यात्रा पर 50,001 पंक्तियों को उत्पन्न करता है, दूसरे पर 50,002 ... और इसी तरह। तालिका चर को पुनरावृत्तियों के बीच 'दूर फेंक दिया' (काट दिया गया) है, इसलिए प्रत्येक पाँच कॉल पूर्ण जनसंख्या है। यही कारण है कि यह इतना धीमा है, और प्रत्येक पंक्ति को परिणाम में दिखाई देने के लिए समान समय लगता है।

साइड नोट्स:

स्वाभाविक रूप से, ऊपर का परिदृश्य यह दिखाने के लिए जानबूझकर वंचित है कि प्रदर्शन कितना खराब हो सकता है जब एमएसटीवीएफ प्रत्येक पुनरावृत्ति पर कई पंक्तियों को पॉप्युलेट करता है।

उपरोक्त कोड का एक समझदार कार्यान्वयन दोनों msTVF मापदंडों को निर्धारित करेगा iऔर निरर्थक WHEREखंड को हटा देगा । टेबल वेरिएबल को अभी भी प्रत्येक पुनरावृत्ति पर छोटा और पुन: आकार दिया जाएगा, लेकिन हर बार केवल एक पंक्ति के साथ।

हम न्यूनतम चरणों में अधिकतम और अधिकतम iमूल्य प्राप्त कर सकते हैं Tऔर उन्हें एक पूर्व चरण में चर में संग्रहीत कर सकते हैं। सहसंबद्ध मापदंडों के बजाय चर के साथ फ़ंक्शन को कॉल करने से 'स्थिर' तालिका चर पैटर्न का उपयोग किया जा सकेगा।

अपरिवर्तित सहसंबद्ध मापदंडों के लिए कैशिंग

मूल प्रश्न को एक बार फिर से लौटाना, जहां अनुक्रम स्थिर पैटर्न का उपयोग नहीं किया जा सकता है, SQL सर्वर ट्रेंकुलेटिंग और पुन: उपयोग करने से बच सकता है अगर कोई नेस्टर्ड लूप के पूर्व चलना के बाद से कोई भी सहसंबंधित पैरामीटर नहीं बदला है।

इसे प्रदर्शित करने के लिए, हम Tपाँच समान i मूल्यों वाली सामग्रियों को प्रतिस्थापित करेंगे :

TRUNCATE TABLE dbo.T;

INSERT dbo.T (i) 
VALUES (50005), (50005), (50005), (50005), (50005);

एक सहसंबद्ध पैरामीटर के साथ क्वेरी फिर से:

SELECT T.i,
       IR.n,
       IR.ts
FROM dbo.T AS T
CROSS APPLY dbo.IntegerRange(1, T.i) AS IR
WHERE IR.n = T.i;

इस बार परिणाम लगभग 1.5 सेकंड में दिखाई देते हैं :

पहचान पंक्ति

प्रत्येक पंक्ति पर समान टाइमस्टैम्प पर ध्यान दें। तालिका चर में कैश्ड परिणाम का पुन: उपयोग इसके पुनरावृत्तियों के लिए किया जाता है जहाँ सहसंबंधित मूल्य iअपरिवर्तित होता है। हर बार 50,005 पंक्तियों को सम्मिलित करने की तुलना में परिणाम का पुन: उपयोग बहुत तेजी से होता है।

निष्पादन योजना पहले की तरह ही दिखती है:

समान पंक्तियों के लिए योजना

मुख्य अंतर तालिका मान्य फ़ंक्शन ऑपरेटर के वास्तविक रिबाइंड और वास्तविक रिवाइंड गुणों में है:

संचालक गुण

जब सहसंबद्ध पैरामीटर नहीं बदलते हैं, तो SQL सर्वर तालिका चर में वर्तमान परिणामों को फिर से खोल (रिवाइंड) कर सकता है। जब सहसंबंध बदल जाता है, तो SQL सर्वर को टेबल चर (रिबंड) को छोटा करना और फिर से बनाना होगा। एक विद्रोह पहली यात्रा पर होता है; चार बाद के पुनरावृत्तियों सभी के बाद से रिवाइंड हैं क्योंकि मूल्य T.iअपरिवर्तित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.