इन समान प्रश्नों के लिए अलग-अलग अनुकूलन चरणों (लेनदेन प्रसंस्करण बनाम त्वरित योजना) का उपयोग क्यों किया जाता है?


12

इस कनेक्ट आइटम में उदाहरण कोड

एक बग दिखाता है जहां

SELECT COUNT(*)
FROM   dbo.my_splitter_1('2') L1
       INNER JOIN dbo.my_splitter_1('') L2
         ON L1.csv_item = L2.csv_item

सही परिणाम देता है। लेकिन निम्नलिखित गलत परिणाम देता है (2014 में नए कार्डिनैलिटी एस्टीमेटर का उपयोग करके)

SELECT
    (SELECT COUNT(*)
    FROM dbo.my_splitter_1('2') L1
     INNER JOIN dbo.my_splitter_1('') L2
        ON L1.csv_item = L2.csv_item)

चूंकि यह L2 के परिणामों को एक सामान्य उप अभिव्यक्ति स्पूल में गलत तरीके से लोड करता है, इसलिए L1 परिणाम के लिए इसके परिणाम को फिर से बताता है।

मैं इस बात को लेकर उत्सुक था कि दो प्रश्नों के बीच व्यवहार में अंतर क्यों है। ट्रेस फ्लैग 8675 से पता चलता है कि जो काम करता है वह प्रवेश करता है search(0) - transaction processingऔर जो असफल होता है वह प्रवेश करता है search(1) - quick plan

इसलिए मैं मानता हूं कि व्यवहार में अंतर के पीछे अतिरिक्त परिवर्तन नियमों की उपलब्धता है (BuildGbApply या GenGbApplySimple को अक्षम करना उदाहरण के लिए इसे ठीक करना प्रतीत होता है)।

लेकिन इन समान प्रश्नों के लिए दो योजनाएं अलग-अलग अनुकूलन चरणों का सामना क्यों करती हैं? मैंने जो पढ़ा search (0)है, उसके लिए कम से कम तीन तालिकाओं की आवश्यकता होती है और यह शर्त निश्चित रूप से पहले उदाहरण में नहीं मिलती है।

जवाबों:


7

प्रत्येक चरण में प्रवेश की स्थिति है। "कम से कम तीन टेबल संदर्भ होने" में से एक प्रवेश की स्थिति है जो हम साधारण उदाहरण देते समय बात करते हैं, लेकिन यह केवल एक ही नहीं है।

आमतौर पर, केवल मूल जोड़ और यूनियनों को खोज 0 में प्रवेश के लिए अनुमति दी जाती है; स्केलर सबक्वेरीज़, सेमी जॉइन्ट्स आदि एंट्री को सर्च करने से रोकते हैं। यह स्टेज वास्तव में बहुत ही सामान्य ओएलटीपी-टाइप क्वेरी शेप के लिए है। कम सामान्य चीजों का पता लगाने के लिए आवश्यक नियम अभी सक्षम नहीं हैं। आपके उदाहरण क्वेरी में एक स्केलर सबक्वेरी है, इसलिए यह प्रविष्टि को विफल करता है।

यह इस बात पर भी निर्भर करता है कि आप तालिका संदर्भों की गणना कैसे करते हैं। मैंने कभी भी इसे कार्यों के साथ गहराई से नहीं देखा है, लेकिन यह संभव है कि तर्क तालिका मान्य कार्यों के साथ-साथ उनके द्वारा उत्पादित तालिका चर भी गिन रहा है। यह फ़ंक्शन के अंदर तालिका संदर्भ भी गिन सकता है - मुझे यकीन नहीं है; हालांकि मुझे पता है कि कार्य पूरे दौर में कठिन परिश्रम हैं।

बग के साथ GenGbApplySimpleबदसूरत है। यह योजना आकार हमेशा एक संभावना थी, लेकिन लागत कारणों से खारिज कर दिया गया था जब तक कि 100-पंक्तियों के परिवर्तन से टेबल चर कार्डिनैलिटी में परिवर्तन नहीं हुआ था। यह 2014 के पूर्व पर समस्याग्रस्त योजना के आकार को USE PLANसंकेत के साथ मजबूर करना संभव है , उदाहरण के लिए।

आप के बारे में सही कर रहे हैं नए कनेक्ट आइटम जा रहा है एक ही मुद्दा पहले से सूचना दी

एक उदाहरण प्रदान करने के लिए, निम्नलिखित प्रश्न खोज 0 के लिए योग्य है:

DECLARE @T AS table (c1 integer NULL);

SELECT U.c1, rn = ROW_NUMBER() OVER (ORDER BY U.c1) 
FROM 
(
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
) AS U;

एक स्केलर सबक्वेरी को शामिल करने के लिए एक छोटा सा बदलाव करना इसका मतलब है कि यह सीधे खोज 1 पर जाता है:

DECLARE @T AS table (c1 integer NULL);

SELECT U.c1, rn = ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -- Changed!
FROM 
(
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
    UNION
    SELECT c1 FROM @T AS T
) AS U;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.