SQL सर्वर कैसे जानता है कि विधेय सहसंबद्ध हैं?


15

SQL सर्वर 2008 R2 क्वेरी को खराब कार्डिनैलिटी अनुमान (सरल अनुक्रमण, अप-टू-डेट आँकड़े, आदि) और इसलिए खराब क्वेरी योजनाओं के साथ निदान करते समय, मुझे एक संभव-संबंधित KB आलेख मिला: FIX: खराब प्रदर्शन जब आप कोई क्वेरी चलाते हैं जिसमें SQL Server 2008 में या SQL Server 2008 R2 में या SQL Server 2012 में सहसंबद्ध और भविष्यवाणी की गई है

मैं अनुमान लगा सकता हूँ कि KB लेख का क्या अर्थ है "सहसंबद्ध", उदाहरण के लिए # 2 का अनुमान लगाएं और # 1 का अनुमान लगाने से मोटे तौर पर समान पंक्तियों को लक्षित करें।

लेकिन मुझे नहीं पता कि SQL सर्वर इन सहसंबंधों के बारे में कैसे जानता है। क्या एक टेबल को दोनों विधेयकों के कॉलम वाले मल्टी-कॉलम इंडेक्स की आवश्यकता होती है? क्या एसक्यूएल आंकड़ों का उपयोग यह जांचने के लिए करता है कि क्या एक कॉलम से दूसरे में मान जुड़ा हुआ है? या कुछ अन्य विधि का उपयोग किया जाता है?

मैं यह दो कारणों से पूछ रहा हूं:

  1. यह निर्धारित करने के लिए कि इस हॉटफ़िक्स का उपयोग करके मेरी कौन सी तालिका और क्वेरीज़ में सुधार किया जा सकता है
  2. यह जानने के लिए कि मुझे # 1 को प्रभावित करने के लिए अनुक्रमण, सांख्यिकी आदि में क्या करना चाहिए

जवाबों:


20

नीचे दिखाए गए सरल AdventureWorks क्वेरी और निष्पादन योजना पर विचार करें। क्वेरी में शामिल होने के लिए पूर्वानुमान शामिल हैं ANDआशावादी की कार्डिनैलिटी का अनुमान 41,211 पंक्तियाँ हैं:

-- Estimate 41,211 rows
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE 
    TH.TransactionID BETWEEN 100000 AND 168336
    AND TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13';

डिफ़ॉल्ट निष्पादन योजना

डिफ़ॉल्ट आँकड़ों का उपयोग करना

केवल एकल-स्तंभ आँकड़ों को देखते हुए, आशावादी इस अनुमान को प्रत्येक अलग के लिए कार्डिनैलिटी का अनुमान लगाकर उत्पन्न करता है, और परिणामी चयनियों को एक साथ गुणा करता है। यह अनुमानवादी मानता है कि विधेय पूरी तरह से स्वतंत्र हैं।

क्वेरी को दो भागों में विभाजित करने से गणना को देखना आसान हो जाता है:

-- Estimate 68,336.4 rows
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE 
    TH.TransactionID BETWEEN 100000 AND 168336;

लेन-देन इतिहास तालिका में कुल 113,443 पंक्तियाँ हैं, इसलिए 68,336.4 अनुमान इस विधेय के लिए 68336.4 / 113443 = 0.60238533 की चयनात्मकता का प्रतिनिधित्व करता है। यह अनुमान TransactionIDस्तंभ के लिए हिस्टोग्राम जानकारी और क्वेरी में निर्दिष्ट निरंतर मानों का उपयोग करके प्राप्त किया जाता है ।

-- Estimate 68,413 rows
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE 
    TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13';

इस विधेय की अनुमानित चयनात्मकता 68413.0 / 113443 = 0.60306056 है । फिर से, यह विधेय के स्थिर मूल्यों और TransactionDateसांख्यिकी ऑब्जेक्ट के हिस्टोग्राम से गणना की जाती है ।

यह मानते हुए कि विधेय पूरी तरह से स्वतंत्र हैं, हम दो विधेयकों की चयनात्मकता का अनुमान एक साथ गुणा करके लगा सकते हैं। आधार कार्ड में 113,443 पंक्तियों द्वारा परिणामी चयनात्मकता को गुणा करके अंतिम कार्डिनलिटी अनुमान प्राप्त किया जाता है:

0.60238533 * 0.60306056 * 113443 = 41210.987

गोलाई के बाद, यह मूल प्रश्न में देखा गया 41,211 अनुमान है (आशावादी आंतरिक रूप से फ्लोटिंग पॉइंट गणित का भी उपयोग करता है)।

एक महान अनुमान नहीं

TransactionIDऔर TransactionDateकॉलम (होगा- बढ़ती कुंजी और तिथि कॉलम अक्सर करते हैं) AdventureWorks डेटा सेट में एक करीबी संबंध हो। इस सहसंबंध का मतलब है कि स्वतंत्रता की धारणा का उल्लंघन किया गया है। परिणामस्वरूप, निष्पादन के बाद की क्वेरी योजना अनुमानित 41,211 के बजाय 68,095 पंक्तियों को दिखाती है:

निष्पादन के बाद की योजना

ट्रेस ध्वज 4137

इस ट्रेस ध्वज को सक्षम करने से विधेय को संयोजित करने के लिए उपयोग किए जाने वाले उत्तराधिकार बदल जाते हैं। पूर्ण स्वतंत्रता मानने के बजाय, ऑप्टिमाइज़र का मानना ​​है कि दो विधेयकों की पसंद काफी करीब हैं कि उनके सहसंबंधित होने की संभावना है:

-- Estimate 68,336.4
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE 
    TH.TransactionID BETWEEN 100000 AND 168336
    AND TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13'
OPTION (QUERYTRACEON 4137);

स्मरण करो कि TransactionIDअकेले विधेय ने 68,336.4 पंक्तियों और अनुमान लगायाTransactionDate अकेले विधेयकों ने 68,413 पंक्तियों का अनुमान लगाया है। ऑप्टिमाइज़र ने इन दोनों अनुमानों में से कई का चयन करने के बजाय चयनकर्ताओं को गुणा किया है।

यह निश्चित रूप से एक अलग अनुमानात्मक है, लेकिन एक है जो सहसंबद्ध ANDविधेय के साथ प्रश्नों के अनुमानों को बेहतर बनाने में मदद कर सकता है। प्रत्येक विधेय को संभावित सहसंबंध के लिए माना जाता है, और कई समायोजन ANDशामिल होने पर किए गए अन्य समायोजन होते हैं, लेकिन यह उदाहरण इसके मूल आधार को दिखाने का कार्य करता है।

मल्टी-कॉलम आँकड़े

ये सहसंबंधों के साथ प्रश्नों में मदद कर सकते हैं, लेकिन हिस्टोग्राम की जानकारी अभी भी केवल आंकड़ों के प्रमुख स्तंभ पर आधारित है। निम्न उम्मीदवार बहु-स्तंभ आँकड़े इसलिए महत्वपूर्ण तरीके से भिन्न होते हैं:

CREATE STATISTICS
    [stats Production.TransactionHistory TransactionID TransactionDate]
ON Production.TransactionHistory
    (TransactionID, TransactionDate);

CREATE STATISTICS
    [stats Production.TransactionHistory TransactionDate TransactionID]
ON Production.TransactionHistory
    (TransactionDate, TransactionID);

उनमें से सिर्फ एक को लेते हुए, हम देख सकते हैं कि एकमात्र अतिरिक्त जानकारी 'सभी' घनत्व के अतिरिक्त स्तर हैं। हिस्टोग्राम में अभी भी केवल TransactionDateकॉलम के बारे में विस्तृत जानकारी है ।

DBCC SHOW_STATISTICS
    (
        'Production.TransactionHistory', 
        'stats Production.TransactionHistory TransactionDate TransactionID'
    );

मल्टी-कॉलम स्टैटिस्टिक

जगह में इन बहु-स्तंभ आंकड़ों के साथ ...

SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE 
    TH.TransactionID BETWEEN 100000 AND 168336
    AND TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13';

... निष्पादन योजना एक अनुमान दिखाती है जो ठीक उसी तरह है जब केवल एकल-स्तंभ आँकड़े उपलब्ध थे:

मल्टी-कॉलम सांख्यिकी योजना

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