सेट अप
मुझे कार्डिनैलिटी के अनुमान को समझने में थोड़ी परेशानी हो रही है। यहाँ मेरा परीक्षण सेटअप है:
- स्टैक ओवरफ्लो डेटाबेस का 2010 संस्करण
- SQL सर्वर 2017 CU15 + GDR (KB4505225) - 14.0.3192.2
- नया CE (संगतता स्तर 140)
मैं इस proc है:
USE StackOverflow2010;
GO
CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount
@CommentCount int
AS
BEGIN
SELECT *
FROM dbo.Posts p
WHERE
p.CommentCount = @CommentCount
OPTION (RECOMPILE);
END;
GO
dbo.Posts
टेबल पर कोई भी गैर-अनुक्रमित सूचकांक या आँकड़े नहीं हैं (कोई क्लस्टर किया गया सूचकांक है Id
)।
इसके लिए एक अनुमानित योजना के लिए पूछने पर, "अनुमानित पंक्तियों" से बाहर आ रहा dbo.Posts
है 1,934.99:
EXEC #sp_PostsByCommentCount @CommentCount = 51;
जब मैंने अनुमानित योजना पूछी तो निम्नलिखित आँकड़े ऑब्जेक्ट स्वचालित रूप से बनाया गया था:
DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]);
उस पर प्रकाश डाला गया हैं:
- आंकड़ों में 1.81% (67,796 / 3,744,192) की कम नमूना दर है
- केवल 31 हिस्टोग्राम चरणों का उपयोग किया गया था
- "सभी घनत्व" मान है
0.03030303
(33 अलग-अलग मूल्य नमूने थे) RANGE_HI_KEY
हिस्टोग्राम में अंतिमEQ_ROWS
1 के साथ 50 है
सवाल
509 (2,147,483,647 तक) और 1,934.99 पंक्ति अनुमान में परिणाम से अधिक किसी भी मूल्य को पास करना। इस अनुमान को बनाने के लिए किस गणना या मूल्य का उपयोग किया जाता है? विरासत कार्डिनैलिटी का अनुमान लगाने वाला 1 पंक्ति का अनुमान लगाता है।
जो मैंने कोशिश की है
यहाँ कुछ सिद्धांत हैं, जो मैंने कोशिश की थी, या जानकारी के अतिरिक्त बिट्स जो मैं इसे देखने के दौरान खुदाई करने में सक्षम था।
घनत्व वेक्टर
मैंने शुरू में सोचा था कि यह घनत्व सदिश होगा, जैसा कि मैंने इस्तेमाल किया था OPTION (OPTIMIZE FOR UNKNOWN)
। लेकिन इस आँकड़े ऑब्जेक्ट के लिए घनत्व वेक्टर 3,744,192 * 0.03030303 = 113,460 है, इसलिए यह नहीं है।
विस्तारित कार्यक्रम
मैंने एक विस्तारित ईवेंट सत्र चलाने की कोशिश की query_optimizer_estimate_cardinality
जिसने इस घटना को एकत्र किया (जो मुझे पॉल व्हाइट के ब्लॉग पोस्ट कार्डिनैलिटी एस्टिमेशन: कॉम्बिनेशन डेंसिटी स्टैटिस्टिक्स से पता चला ), और इस तरह के दिलचस्प टिडबेट्स मिले:
<CalculatorList>
<FilterCalculator CalculatorName="CSelCalcColumnInInterval" Selectivity="-1.000"
CalculatorFailed="true" TableName="[p]" ColumnName="CommentCount" />
<FilterCalculator CalculatorName="CSelCalcAscendingKeyFilter" Selectivity="0.001"
TableName="[p]" ColumnName="CommentCount" UseAverageFrequency="true"
StatId="4" />
</CalculatorList>
तो ऐसा प्रतीत होता है कि CSelCalcAscendingKeyFilter
कैलकुलेटर का उपयोग किया गया था (दूसरा कहता है कि यह विफल हो गया, जो भी इसका मतलब है)। यह कॉलम एक कुंजी, या अद्वितीय या आवश्यक रूप से आरोही नहीं है, लेकिन जो भी हो।
उस शब्द के कुछ Googling करने से मुझे कुछ ब्लॉग पोस्ट में ले जाया गया:
- जो बोरी - CSelCalcAscendingKeyFilter कैलकुलेटर ,
- इत्ज़िक बेन-गान - सीक एंड यू शल स्कैन पार्ट II: आरोही कुंजी
ये पोस्ट नए सीई आधारों को घनत्व वेक्टर के संयोजन और स्टेट के संशोधन काउंटर पर इन बाहरी-हिस्टोग्राम अनुमानों का संकेत देते हैं। दुर्भाग्य से, मैं पहले से ही घनत्व वेक्टर से इनकार कर चुका हूं (मुझे लगता है ?!), और संशोधन काउंटर शून्य (प्रति sys.dm_db_stats_properties
भी) है।
ट्रेस झंडे
फॉरेस्ट ने सुझाव दिया कि मैं अनुमान प्रक्रिया के बारे में कुछ और जानकारी प्राप्त करने के लिए TF 2363 को चालू कर दूंगा। मुझे लगता है कि आउटपुट से सबसे प्रासंगिक बात यह है:
Plan for computation:
CSelCalcAscendingKeyFilter(avg. freq., QCOL: [p].CommentCount)
Selectivity: 0.000516798
यह एक सफलता है (धन्यवाद, फॉरेस्ट!): उस 0.000516798
संख्या (जो Selectivity="0.001"
ऊपर XE विशेषता में अनपेक्षित रूप से गोल की गई है) को तालिका में पंक्तियों की संख्या से गुणा किया गया है वह अनुमान है जो मैं देख रहा हूं (1,934.99)।
मैं शायद कुछ स्पष्ट याद कर रहा हूं, लेकिन मैं इंजीनियर को रिवर्स करने में सक्षम नहीं हूं कि CSelCalcAscendingKeyFilter
कैलकुलेटर के अंदर चयनात्मकता मूल्य कैसे उत्पन्न होता है ।