फ़ंक्शन कॉल के साथ अनुमानित बनाम वास्तविक क्वेरी योजना


11

मेरे पास SQL ​​सर्वर पर यह क्वेरी है, मर्ज प्रतिकृति क्वेरी:

SELECT DISTINCT
    b.tablenick,
    b.rowguid,
    c.generation,
    sys.fn_MSgeneration_downloadonly
    (
        c.generation,
        c.tablenick
    )
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON 
    c.tablenick = b.tablenick
    AND c.rowguid = b.rowguid;

अनुमानित क्वेरी योजना में 3 प्रश्नों के बारे में जानकारी शामिल है:

  1. ऊपर की क्वेरी
  2. फ़ंक्शन fn_MSgeneration_downloadonly पर कॉल करता है
  3. फ़ंक्शन fn_MSArticle_has_downloadonly_property पर कॉल करता है

वास्तविक क्वेरी योजना में केवल यह जानकारी शामिल है:

  1. ऊपर की क्वेरी

कार्यों के बारे में कुछ भी नहीं। वास्तविक योजना में फ़ंक्शन जानकारी क्यों गायब है?

मैंने इन विकल्पों की कोशिश की:

SET STATISTICS PROFILE ON
SET STATISTICS XML ON

जिसने एक वास्तविक योजना बनाई थी, लेकिन जब मैं प्रबंधन स्टूडियो में वास्तविक क्वेरी योजना विकल्प का उपयोग करता था तो यह भागों 2 और 3 को याद कर रहा था।

यदि उदाहरण के लिए, मैं फ़ंक्शन कॉल के बारे में जानकारी प्राप्त करने के लिए Profiler का उपयोग करता था तो मैं किन घटनाओं का चयन करूंगा?


विशेष रूप से क्वेरी योजनाओं से संबंधित उत्तर नहीं मिला, लेकिन मैंने SP: StmtStarting और SP: StmtCompleted को देखा और इसने फ़ंक्शन कॉल को दिखाया।

जवाबों:


17

और कार्यों के बारे में कुछ भी नहीं। वास्तविक योजना में फ़ंक्शन जानकारी क्यों गायब है?

यह प्रदर्शन कारणों से डिजाइन के अनुसार है।

कार्य BEGINऔर ENDपरिभाषा में प्रत्येक इनपुट पंक्ति के लिए एक नया T-SQL स्टैक फ्रेम बनाते हैं। एक और तरीका रखो, फ़ंक्शन बॉडी को प्रत्येक इनपुट पंक्ति के लिए अलग से निष्पादित किया जाता है । यह एकल तथ्य टी-एसक्यूएल स्केलर और मल्टी-स्टेटमेंट फ़ंक्शन (नोट इन-लाइन टेबल वैल्यू फ़ंक्शंस BEGIN...ENDसिंटैक्स का उपयोग नहीं करता है) से जुड़ी अधिकांश प्रदर्शन समस्याओं की व्याख्या करता है ।

आपके प्रश्न के संदर्भ में, इसके परिणामस्वरूप SHOWPLANप्रत्येक पंक्ति के लिए पूर्ण आउटपुट होगा । एक्सएमएल प्लान आउटपुट काफी क्रियात्मक और महंगा है, इसलिए हर पंक्ति के लिए पूर्ण आउटपुट का उत्पादन सामान्य शब्दों में एक बुरा विचार होगा।

उदाहरण

नीचे दिए गए T- SQL स्केलर फ़ंक्शन पर विचार करें , जो AdventureWorks नमूना डेटाबेस में बनाया गया है , जो किसी उत्पाद का नाम उसकी आईडी देता है:

CREATE FUNCTION dbo.DumbNameLookup
(
    @ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
    RETURN
    (
        SELECT
            p.Name
        FROM Production.Product AS p
        WHERE
            p.ProductID = @ProductID
    );
END;

पूर्व निष्पादन योजना

पूर्व-निष्पादन योजना (SSMS में अनुमानित योजना) मूल विवरण और नेस्टेड फ़ंक्शन कॉल के लिए योजना की जानकारी दिखाती है:

-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;

SSMS आउटपुट:

एसएसएमएस पूर्व-निष्पादन योजना

SQL संतरी प्लान एक्सप्लोरर में देखे गए एक्सएमएल कॉल की नेस्टेड प्रकृति को अधिक स्पष्ट रूप से दिखाता है:

पीई पूर्व निष्पादन योजना

निष्पादन के बाद का उत्पादन

एसएसएमएस केवल मुख्य क्वेरी के लिए विवरण दिखाता है जब पोस्ट-एक्ज़ीक्यूशन प्लान आउटपुट का अनुरोध किया जाता है:

-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;

एसएसएमएस पोस्ट-निष्पादन

अन्यथा करने का प्रदर्शन प्रभाव SQL Server Profiler में Showplan XML सांख्यिकी प्रोफ़ाइल इवेंट क्लास का उपयोग करके, एक क्वेरी का उपयोग करके दिखाया जा सकता है जो फ़ंक्शन को कई बार कॉल करता है (एक बार इनपुट पंक्ति के अनुसार):

SELECT TOP (5)
    p.ProductID,
    dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;

Profiler उत्पादन:

ट्रेस आउटपुट

फ़ंक्शन निष्पादन के लिए पांच अलग-अलग पोस्ट-निष्पादन योजनाएं हैं, और एक पैरेंट क्वेरी के लिए। पांच फंक्शन की योजना इस प्रकार दिखती है लोअर प्रोफाइल

कार्य योजना

मूल क्वेरी योजना है:

जनक की योजना

TOP (5)उत्पाद तालिका में 504 पंक्तियों में से प्रत्येक के लिए पूर्ण निष्पादन योजना में क्लॉज के बिना क्वेरी निष्पादित करने का परिणाम है। आप शायद देख सकते हैं कि यह कैसे जल्दी से बड़ी तालिकाओं के साथ हाथ से निकल जाएगा।

ट्रिगर्स के लिए स्थिति उलट है। ये किसी पूर्व-निष्पादन योजना की जानकारी नहीं दिखाते हैं, लेकिन एक निष्पादन के बाद की योजना को भी शामिल करते हैं। यह ट्रिगर की सेट-आधारित प्रकृति को दर्शाता है; प्रत्येक को एक पंक्ति के बजाय एक बार प्रभावित सभी पंक्तियों के लिए निकाल दिया जाता है।


@PaWWite कोई अच्छा कारण है कि अनुमानित निष्पादन योजना का अनुरोध करते समय ट्रिगर योजनाओं को नहीं दिखाया गया है? यह एक उपयोगी लापता सुविधा की तरह लगता है। मैं इसके लिए एक कनेक्ट आइटम बना सकता हूं।
usr

@usr - हो सकता है क्योंकि जो वास्तविक कैश्ड प्लान चुना गया है वह यहाँ वर्णित पंक्तियों की वास्तविक संख्या पर निर्भर हो सकता है? Technet.microsoft.com/en-us/library/…
मार्टिन स्मिथ

@MartinSmith जो एक कारण हो सकता है। हाल ही में चेक और fk बाधाओं के निष्पादन योजनाओं के लिए एक कनेक्ट आइटम को पूरा होने के रूप में चिह्नित किया गया था, इसलिए मुझे उम्मीद थी कि वे ट्रिगर के साथ भी यही काम करेंगे।
usr

@usr - यह एक यहाँ ? 3 महीने? यह एक नई सुविधा के अनुरोध के लिए रिकॉर्ड होना चाहिए!
मार्टिन स्मिथ

@MartinSmith हाँ, वह एक। यह 1-2 साल पहले "तय" था। मुझे वास्तव में उम्मीद है कि मुझे क्वेरी स्टोर को क्वेरी करने की ज़रूरत नहीं है। मुझे SSMS में एक बटन पर क्लिक करने की उम्मीद थी। वास्तव में, मैं इंजन के एक हिस्से में किसी भी परिवर्तन को देखकर आश्चर्यचकित था जो वर्षों में छुआ नहीं गया था। लेकिन शायद कोई नहीं था।
usr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.