इंट्रा स्टेप सांख्यिकी मूल्य के लिए> => के लिए कार्डिनैलिटी अनुमान


9

मैं यह समझने की कोशिश कर रहा हूं कि SQL सर्वर 2014 में क्लाज के रूप में 'सर्वर से अधिक' और 'के बराबर' के लिए अनुमान लगाने की कोशिश करता है।

मुझे लगता है कि जब मैं उदाहरण के लिए कदम उठाता हूं तो मुझे कार्डिनैलिटी का अनुमान समझ में आता है

    select * from charge where charge_dt >= '1999-10-13 10:47:38.550'

कार्डिनैलिटी का अनुमान 6672 है जिसे आसानी से 32 (EQ_ROWS) + 6624 (RANGE_ROWS) + 16 (EQ_ROWS) = 6672 (नीचे स्क्रीनशॉट में हिस्टोग्राम) के रूप में गणना की जा सकती है

यहां छवि विवरण दर्ज करें

लेकिन जब मैं करता हूं

    select * from charge where charge_dt >= '1999-10-13 10:48:38.550' 

(समय बढ़ाकर 10:48 किया गया, इसलिए यह एक कदम नहीं है)

अनुमान 4844.13 है।

यह कैसे गणना की जाती है?

जवाबों:


9

एकमात्र कठिनाई यह तय करने में है कि हिस्टोग्राम कदम (स) को आंशिक रूप से क्वेरी के द्वारा कवर किए गए अंतराल को कैसे संभालना है । प्रेडिकेट रेंज द्वारा कवर किए गए पूरे हिस्टोग्राम कदम तुच्छ हैं जैसा कि प्रश्न में उल्लेख किया गया है।

लिगेसी कार्डिनैलिटी एस्टीमेटर

F = क्वेरी सीमा द्वारा कवर चरण सीमा के (0 और 1 के बीच) का अंश।

मूल विचार का उपयोग करना है F(रैखिक प्रक्षेप) यह निर्धारित करने के लिए कि कितने अंतर-चरण अलग-अलग मूल्यों को विधेय द्वारा कवर किया गया है। इस परिणाम को अलग-अलग मूल्य की पंक्तियों की औसत मान (एकरूपता मानकर) से गुणा करें और चरण बराबर पंक्तियों को जोड़ने से कार्डिनैलिटी का अनुमान मिलता है:

कार्डिनैलिटी = EQ_ROWS + (AVG_RANGE_ROWS * F * DISTINCT_RANGE_ROWS)

उसी सूत्र का उपयोग >और >=विरासत CE में किया जाता है ।

नई कार्डिनैलिटी एस्टीमेटर

नया CE पिछले एल्गोरिथ्म को थोड़ा अलग करता है >और दोनों के बीच अंतर करता है >=

>पहले लेना , सूत्र है:

कार्डिनैलिटी = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))

इसके लिए >=यह है:

कार्डिनैलिटी = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))

यह + 1दर्शाता है कि जब तुलना में समानता शामिल होती है, तो एक मैच मान लिया जाता है (समावेशन धारणा)।

प्रश्न के उदाहरण में, Fइसकी गणना इस प्रकार की जा सकती है:

DECLARE 
    @Q datetime = '1999-10-13T10:48:38.550',
    @K1 datetime = '1999-10-13T10:47:38.550',
    @K2 datetime = '1999-10-13T10:51:19.317';

DECLARE
    @QR float = DATEDIFF(MILLISECOND, @Q, @K2), -- predicate range
    @SR float = DATEDIFF(MILLISECOND, @K1, @K2) -- whole step range

SELECT
    F = @QR / @SR;

परिणाम 0.728219019233034 है>=अन्य ज्ञात मूल्यों के साथ सूत्र में प्लगिंग :

कार्डिनैलिटी = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
            = 16 + (16.1956 * ((0.728219019233034 * (409 - 1)) + 1)
            = 16 + (16.1956 * ((0.728219019233034 * 408) + 1))
            = 16 + (16.1956 * (297.113359847077872 + 1)
            = 16 + (16.1956 * 298.113359847077872)
            = 16 + 4828.1247307393343837632
            = 4844.1247307393343837632
            = 4844.12473073933 (सटीक तैरने के लिए)

यह परिणाम प्रश्न में दिखाए गए 4844.13 के अनुमान से सहमत है।

विरासत सीई (उदाहरण के झंडे 9481 का उपयोग करके) का उपयोग करते हुए एक ही क्वेरी का अनुमान लगाना चाहिए:

कार्डिनैलिटी = EQ_ROWS + (AVG_RANGE_ROWS * F * DISTINCT_RANGE_ROWS)
            = 16 + (16.1956 * 0.728219019233034 * 409)
            = 16 + 4823.72307468722
            = 4839.72307468722

ध्यान दें कि अनुमान विरासत CE के उपयोग >और >=उपयोग के लिए समान होगा ।


4

पंक्तियों का अनुमान लगाने का सूत्र थोड़ा नासमझ हो जाता है जब फ़िल्टर "से अधिक" या "से कम" होता है, लेकिन यह एक संख्या है जिस पर आप पहुंच सकते हैं।

संख्याएँ

चरण 193 का उपयोग करते हुए, यहां प्रासंगिक संख्याएं हैं:

RANGE_ROWS = 6624

EQ_ROWS = 16

AVG_RANGE_ROWS = 16.1956

RANGE_HI_KEY पिछले चरण से = 1999-10-13 10: 47: 38.550

वर्तमान चरण = 1999-10-13 10: 51: 19.317 से RANGE_HI_KEY

WHERE क्लॉज से मूल्य = 1999-10-13 10: 48: 38.550

सूत्र

1) दो रेंज हाय की के बीच एमएस को खोजें

SELECT DATEDIFF (ms, '1999-10-13 10:47:38.550', '1999-10-13 10:51:19.317')

परिणाम 220767 एमएस है।

2) पंक्तियों की संख्या को समायोजित करें

हमें प्रति मिलीसेकंड पंक्तियों को खोजने की आवश्यकता है, लेकिन इससे पहले कि हम ऐसा करें, हमें AVG_RANGE_ROWS को RANGE_ROWS से घटाना होगा:

6624 - 16.1956 = 6607.8044 पंक्तियाँ

3) पंक्तियों की समायोजित संख्या के साथ ms प्रति पंक्तियों की गणना करें:

6607.8044 पंक्तियों / 220767 एमएस = .0299311 पंक्तियों प्रति एमएस

4) WHERE क्लॉज और मौजूदा चरण RANGE_HI_KEY से मूल्य के बीच एमएस की गणना करें

SELECT DATEDIFF (ms, '1999-10-13 10:48:38.550', '1999-10-13 10:51:19.317')

यह हमें 160767 एमएस देता है।

5) प्रति सेकंड पंक्तियों के आधार पर इस चरण में पंक्तियों की गणना करें:

.0299311 पंक्तियाँ / एमएस * 160767 एमएस = 4811.9332 पंक्तियाँ

6) याद रखें कि हमने पहले AVG_RANGE_ROWS को कैसे घटाया? उन्हें वापस जोड़ने का समय। अब जब हम प्रति सेकंड पंक्तियों से संबंधित संख्याओं की गणना कर रहे हैं, हम सुरक्षित रूप से EQ_ROWS भी जोड़ सकते हैं:

4811.9332 + 16.1956 + 16 = 4844.1288

गोल है, यह हमारा 4844.13 अनुमान है।

सूत्र का परीक्षण

AVG_RANGE_ROWS प्रति ms की पंक्तियों की गणना करने से पहले क्यों घटाया जाता है, इस पर मुझे कोई लेख या ब्लॉग पोस्ट नहीं मिला। मैं पुष्टि करने में सक्षम था कि वे अनुमान के लिए जिम्मेदार हैं, लेकिन केवल अंतिम मिलीसेकंड पर - शाब्दिक रूप से।

वाइडवर्ल्डइम्पोर्टर्स डेटाबेस का उपयोग करते हुए , मैंने कुछ वृद्धिशील परीक्षण किया और पाया कि चरण के अंत तक पंक्ति अनुमानों में कमी रेखीय हो सकती है , जहां 1x AVG_RANGE_ROWS का अचानक हिसाब लगाया जाता है।

यहाँ मेरा नमूना प्रश्न है:

SELECT PickingCompletedWhen
FROM Sales.Orders
WHERE PickingCompletedWhen >= '2016-05-24 11:00:01.000000'

मैंने PickingCompletedWhen के आंकड़ों को अपडेट किया, फिर हिस्टोग्राम मिला:

DBCC SHOW_STATISTICS([sales.orders], '_WA_Sys_0000000E_44CA3770')

_WA_Sys_0000000E_44CA3770 के लिए हिस्टोग्राम (अंतिम 3 चरण)

यह देखने के लिए कि अनुमानित पंक्तियाँ कैसे घटती हैं क्योंकि हम RANGE_HI_KEY से संपर्क करते हैं, मैंने चरण भर में नमूने एकत्र किए। कमी रेखीय है, लेकिन व्यवहार करता है जैसे कि AVG_RANGE_ROWS मान के बराबर कई पंक्तियाँ सिर्फ प्रवृत्ति का हिस्सा नहीं हैं ... जब तक आप RANGE_HI_KEY को हिट नहीं करते और अचानक वे बंद लिखे गए बिना छूटे ऋण की तरह गिर जाते हैं। आप इसे नमूना डेटा में देख सकते हैं, विशेष रूप से ग्राफ़ में।

यहां छवि विवरण दर्ज करें

पंक्तियों में स्थिर गिरावट पर ध्यान दें जब तक हम RANGE_HI_KEY को हिट नहीं करते हैं और तब BOOM कि पिछले AVG_RANGE_ROWS चंक को अचानक घटाया जाता है। यह एक ग्राफ में भी हाजिर करना आसान है।

यहां छवि विवरण दर्ज करें

योग करने के लिए, AVG_RANGE_ROWS का विषम उपचार, गणना के अनुमानों को अधिक जटिल बनाता है, लेकिन आप हमेशा यह समझ सकते हैं कि सीई क्या कर रहा है।

एक्सपोनेंशियल बैकऑफ के बारे में क्या?

एक्सपोनेंशियल बैकऑफ़ एक नया तरीका है (एसक्यूएल सर्वर 2014 के अनुसार) कार्डिनलिटी एस्टिमेटर कई एकल-कॉलम आँकड़ों का उपयोग करते समय बेहतर अनुमान प्राप्त करने के लिए उपयोग करता है। चूंकि यह प्रश्न एक एकल-स्तंभ स्टेट के बारे में था, इसलिए इसमें EB सूत्र शामिल नहीं है।

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