सांख्यिकी में कितने हिस्टोग्राम कदम तय किए गए हैं


11

SQL सर्वर में सांख्यिकी में हिस्टोग्राम चरणों की संख्या कैसे तय की जाती है?

मेरे प्रमुख कॉलम में 200 से अधिक भिन्न मान होने के बावजूद इसे 200 चरणों तक ही सीमित क्यों रखा गया है? क्या कोई निर्णायक कारक है?


डेमो

स्कीमा की परिभाषा

CREATE TABLE histogram_step
  (
     id   INT IDENTITY(1, 1),
     name VARCHAR(50),
     CONSTRAINT pk_histogram_step PRIMARY KEY (id)
  )

मेरी तालिका में 100 रिकॉर्ड सम्मिलित करें

INSERT INTO histogram_step
            (name)
SELECT TOP 100 name
FROM   sys.syscolumns

आँकड़ों को अद्यतन और जाँचना

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step)

हिस्टोग्राम कदम:

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|            3 |          1 |       1 |                   1 |              1 |
|            5 |          1 |       1 |                   1 |              1 |
|            7 |          1 |       1 |                   1 |              1 |
|            9 |          1 |       1 |                   1 |              1 |
|           11 |          1 |       1 |                   1 |              1 |
|           13 |          1 |       1 |                   1 |              1 |
|           15 |          1 |       1 |                   1 |              1 |
|           17 |          1 |       1 |                   1 |              1 |
|           19 |          1 |       1 |                   1 |              1 |
|           21 |          1 |       1 |                   1 |              1 |
|           23 |          1 |       1 |                   1 |              1 |
|           25 |          1 |       1 |                   1 |              1 |
|           27 |          1 |       1 |                   1 |              1 |
|           29 |          1 |       1 |                   1 |              1 |
|           31 |          1 |       1 |                   1 |              1 |
|           33 |          1 |       1 |                   1 |              1 |
|           35 |          1 |       1 |                   1 |              1 |
|           37 |          1 |       1 |                   1 |              1 |
|           39 |          1 |       1 |                   1 |              1 |
|           41 |          1 |       1 |                   1 |              1 |
|           43 |          1 |       1 |                   1 |              1 |
|           45 |          1 |       1 |                   1 |              1 |
|           47 |          1 |       1 |                   1 |              1 |
|           49 |          1 |       1 |                   1 |              1 |
|           51 |          1 |       1 |                   1 |              1 |
|           53 |          1 |       1 |                   1 |              1 |
|           55 |          1 |       1 |                   1 |              1 |
|           57 |          1 |       1 |                   1 |              1 |
|           59 |          1 |       1 |                   1 |              1 |
|           61 |          1 |       1 |                   1 |              1 |
|           63 |          1 |       1 |                   1 |              1 |
|           65 |          1 |       1 |                   1 |              1 |
|           67 |          1 |       1 |                   1 |              1 |
|           69 |          1 |       1 |                   1 |              1 |
|           71 |          1 |       1 |                   1 |              1 |
|           73 |          1 |       1 |                   1 |              1 |
|           75 |          1 |       1 |                   1 |              1 |
|           77 |          1 |       1 |                   1 |              1 |
|           79 |          1 |       1 |                   1 |              1 |
|           81 |          1 |       1 |                   1 |              1 |
|           83 |          1 |       1 |                   1 |              1 |
|           85 |          1 |       1 |                   1 |              1 |
|           87 |          1 |       1 |                   1 |              1 |
|           89 |          1 |       1 |                   1 |              1 |
|           91 |          1 |       1 |                   1 |              1 |
|           93 |          1 |       1 |                   1 |              1 |
|           95 |          1 |       1 |                   1 |              1 |
|           97 |          1 |       1 |                   1 |              1 |
|           99 |          1 |       1 |                   1 |              1 |
|          100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

जैसा कि हम देख सकते हैं कि हिस्टोग्राम में 53 चरण हैं।

फिर से कुछ हजार रिकॉर्ड्स डाले

INSERT INTO histogram_step
            (name)
SELECT TOP 10000 b.name
FROM   sys.syscolumns a
       CROSS JOIN sys.syscolumns b

आँकड़ों को अद्यतन और जाँचना

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step)

अब हिस्टोग्राम कदम 4 चरणों तक कम हो गए हैं

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|        10088 |      10086 |       1 |               10086 |              1 |
|        10099 |         10 |       1 |                  10 |              1 |
|        10100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

फिर से कुछ हजार रिकॉर्ड्स डाले

INSERT INTO histogram_step
            (name)
SELECT TOP 100000 b.name
FROM   sys.syscolumns a
       CROSS JOIN sys.syscolumns b

आँकड़ों को अद्यतन और जाँचना

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step) 

अब हिस्टोग्राम कदमों को 3 चरणों तक कम कर दिया जाता है

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|       110099 |     110097 |       1 |              110097 |              1 |
|       110100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

क्या कोई मुझे बता सकता है कि ये कदम कैसे तय किए जाते हैं?


3
200 एक मनमाना विकल्प था। किसी विशिष्ट तालिका में आपके कितने अलग-अलग मूल्य हैं, इसका कोई लेना-देना नहीं है। आप को पता है क्यों 200 चुना गया था चाहते हैं, आप 1990 के दशक एसक्यूएल सर्वर टीम की ओर से एक इंजीनियर पूछा जाएगा नहीं अपने साथियों
हारून बर्ट्रेंड

1
@AaronBertrand - धन्यवाद .. तो ये कदम कैसे तय किए गए
P

1
कोई निर्णय नहीं है। ऊपरी सीमा 200 है। अवधि। ठीक है, तकनीकी रूप से, यह 201 है, लेकिन यह एक और दिन के लिए एक कहानी है।
हारून बर्ट्रेंड

1
मैंने इंट्रास्ट अनुमान के बारे में एक समान प्रश्न पूछा है, सहायक हो सकता है dba.stackexchange.com/questions/148523/…
jesijesi

जवाबों:


14

मैं एकल स्तंभ आँकड़ों पर चर्चा करने के लिए इस पोस्ट को सीमित करने जा रहा हूं क्योंकि यह पहले से ही काफी लंबा हो जाएगा और आप रुचि रखते हैं कि SQL सर्वर डेटा को हिस्टोग्राम चरणों में कैसे बाल्टी करता है। मल्टी कॉलम के आंकड़ों के लिए हिस्टोग्राम केवल प्रमुख कॉलम पर बनाया गया है।

जब SQL सर्वर निर्धारित करता है कि आँकड़ों के अद्यतन की आवश्यकता है तो यह एक छुपी हुई क्वेरी को किक करता है जो तालिका के सभी डेटा या तालिका के डेटा के नमूने को पढ़ता है। आप इन प्रश्नों को विस्तारित घटनाओं के साथ देख सकते हैं। StatManSQL सर्वर के भीतर एक फ़ंक्शन है जिसे हिस्टोग्राम बनाने के साथ शामिल किया गया है। साधारण सांख्यिकी वस्तुओं के लिए कम से कम दो अलग-अलग प्रकार की StatManक्वेरीज़ होती हैं (त्वरित स्टेट्स अपडेट्स के लिए अलग-अलग क्वेश्चन होते हैं और मुझे संदेह है कि विभाजित टेबल पर वृद्धिशील आँकड़े भी एक अलग क्वेरी का उपयोग करते हैं)।

पहला सिर्फ बिना किसी फ़िल्टरिंग के तालिका से सभी डेटा को पकड़ लेता है। आप यह देख सकते हैं जब तालिका बहुत छोटी है या आप FULLSCANविकल्प के साथ आँकड़े एकत्र करते हैं :

CREATE TABLE X_SHOW_ME_STATMAN (N INT);
CREATE STATISTICS X_STAT_X_SHOW_ME_STATMAN ON X_SHOW_ME_STATMAN (N);

-- after gathering stats with 1 row in table
SELECT StatMan([SC0]) FROM
(
    SELECT TOP 100 PERCENT [N] AS [SC0] 
    FROM [dbo].[X_SHOW_ME_STATMAN] WITH (READUNCOMMITTED)
    ORDER BY [SC0] 
) AS _MS_UPDSTATS_TBL 
OPTION (MAXDOP 16);

SQL सर्वर तालिका के आकार के आधार पर स्वचालित नमूना आकार चुनता है (मुझे लगता है कि यह तालिका में पंक्तियों और पृष्ठों दोनों की संख्या है)। यदि कोई तालिका बहुत बड़ी है, तो स्वचालित नमूना आकार 100% से नीचे आता है। यहां 1M पंक्तियों के साथ मुझे वही तालिका मिली है:

-- after gathering stats with 1 M rows in table
SELECT StatMan([SC0], [SB0000]) FROM 
(
    SELECT TOP 100 PERCENT [SC0], step_direction([SC0]) over (order by NULL) AS [SB0000] 
    FROM 
    (
        SELECT [N] AS [SC0] 
        FROM [dbo].[X_SHOW_ME_STATMAN] TABLESAMPLE SYSTEM (6.666667e+001 PERCENT) WITH (READUNCOMMITTED) 
    ) AS _MS_UPDSTATS_TBL_HELPER 
    ORDER BY [SC0], [SB0000] 
) AS _MS_UPDSTATS_TBL
OPTION (MAXDOP 1);

TABLESAMPLEहै प्रलेखित लेकिन StatMan और step_direction नहीं हैं। हिस्टोग्राम बनाने के लिए यहां SQL सर्वर नमूने तालिका से लगभग 66.6% डेटा का नमूना लेता है। इसका मतलब यह है कि आप एक FULLSCANही डेटा पर आँकड़े (बिना ) को अपडेट करते हुए एक अलग संख्या में हिस्टोग्राम कदम उठा सकते हैं । मैंने इसे कभी अभ्यास में नहीं देखा है लेकिन मैं यह नहीं देखता कि यह क्यों संभव नहीं होगा।

आइए सरल आंकड़ों पर कुछ परीक्षण चलाते हैं कि समय के साथ आँकड़े कैसे बदलते हैं। नीचे कुछ परीक्षण कोड हैं जो मैंने अनुक्रमिक पूर्णांक तालिका में सम्मिलित करने के लिए लिखे थे, प्रत्येक प्रविष्टि के बाद आंकड़े इकट्ठा करते हैं, और परिणाम तालिका में आँकड़ों के बारे में जानकारी सहेजते हैं। चलो 10000 तक एक बार में 1 पंक्ति डालने के साथ शुरू करते हैं। टेस्ट बिस्तर:

DECLARE
@stats_id INT,
@table_object_id INT,
@rows_per_loop INT = 1,
@num_of_loops INT = 10000,
@loop_num INT;

BEGIN
    SET NOCOUNT ON;

    TRUNCATE TABLE X_STATS_RESULTS;

    SET @table_object_id = OBJECT_ID ('X_SEQ_NUM');
    SELECT @stats_id = stats_id FROM sys.stats
    WHERE OBJECT_ID = @table_object_id
    AND name = 'X_STATS_SEQ_INT_FULL';

    SET @loop_num = 0;
    WHILE @loop_num < @num_of_loops
    BEGIN
        SET @loop_num = @loop_num + 1;

        INSERT INTO X_SEQ_NUM WITH (TABLOCK)
        SELECT @rows_per_loop * (@loop_num - 1) + N FROM dbo.GetNums(@rows_per_loop);

        UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN; -- can comment out FULLSCAN as needed

        INSERT INTO X_STATS_RESULTS WITH (TABLOCK)
        SELECT 'X_STATS_SEQ_INT_FULL', @rows_per_loop * @loop_num, rows_sampled, steps 
        FROM sys.dm_db_stats_properties(@table_object_id, @stats_id);
        END;
END;

इस डेटा के लिए हिस्टोग्राम के चरणों की संख्या जल्दी से 200 तक बढ़ जाती है (यह पहले 397 पंक्तियों के साथ अधिकतम चरणों को हिट करता है), 199 या 200 पर रहता है जब तक कि 1485 पंक्तियां तालिका में नहीं होती हैं, तब धीरे-धीरे कम हो जाती हैं जब तक कि हिस्टोग्राम केवल 3 या 4 नहीं हो जाता है कदम। यहाँ सभी डेटा का एक ग्राफ है:

पहला ग्राफ

यहाँ हिस्टोग्राम 10k पंक्तियों की तरह दिखता है:

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           1       0                   1
9999            9997        1       9997                1
10000           0           1       0                   1

क्या यह एक समस्या है कि हिस्टोग्राम में केवल 3 चरण होते हैं? ऐसा लगता है कि जानकारी हमारे दृष्टिकोण से संरक्षित है। ध्यान दें कि क्योंकि डेटाटाइप एक INTEGER है जिससे हम यह पता लगा सकते हैं कि 1 - 10000 से प्रत्येक पूर्णांक के लिए तालिका में कितनी पंक्तियाँ हैं। आमतौर पर SQL सर्वर इसका भी पता लगा सकता है, हालाँकि कुछ मामले ऐसे होते हैं जिनमें यह काफी कारगर नहीं होता है । इस उदाहरण के लिए यह एसई पोस्ट देखें ।

आपको क्या लगता है कि अगर हम टेबल से एक भी पंक्ति हटाते हैं और आँकड़े अपडेट करते हैं तो क्या होगा? आदर्श रूप से हमें यह दिखाने के लिए एक और हिस्टोग्राम कदम मिलेगा कि लापता पूर्णांक अब तालिका में नहीं है।

DELETE FROM X_SEQ_NUM
WHERE X_NUM  = 1000;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 3 steps

DELETE FROM X_SEQ_NUM
WHERE X_NUM  IN (2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 3 steps

यह थोड़ा निराशाजनक है। यदि हम हाथ से हिस्टोग्राम का निर्माण कर रहे थे तो हम प्रत्येक लापता मूल्य के लिए एक कदम जोड़ देंगे। एसक्यूएल सर्वर एक सामान्य उद्देश्य एल्गोरिथ्म का उपयोग कर रहा है इसलिए कुछ डेटा सेटों के लिए हम उस कोड की तुलना में अधिक उपयुक्त हिस्टोग्राम के साथ आने में सक्षम हो सकते हैं जो इसका उपयोग करता है। बेशक, किसी तालिका से 0 या 1 पंक्ति प्राप्त करने का व्यावहारिक अंतर बहुत कम है। 20000 पंक्तियों के साथ परीक्षण करते समय मुझे वही परिणाम मिलते हैं जिसमें प्रत्येक पूर्णांक में 2 पंक्तियाँ होती हैं। डेटा डिलीट करते ही हिस्टोग्राम कदम नहीं उठाता।

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           2       0                   1
9999            19994       2       9997                2
10000           0           2       0                   1

यदि मैं प्रत्येक पूर्णांक के साथ 1 मिलियन पंक्तियों के साथ परीक्षण करता हूं जिसमें तालिका में 100 पंक्तियां हैं तो मुझे थोड़ा बेहतर परिणाम मिलता है, लेकिन मैं अभी भी हाथ से बेहतर हिस्टोग्राम का निर्माण कर सकता हूं।

truncate table X_SEQ_NUM;

BEGIN TRANSACTION;
INSERT INTO X_SEQ_NUM WITH (TABLOCK)
SELECT N FROM dbo.GetNums(10000);
GO 100
COMMIT TRANSACTION;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- 4 steps

DELETE FROM X_SEQ_NUM
WHERE X_NUM  = 1000;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- now 5 steps with a RANGE_HI_KEY of 998 (?)

DELETE FROM X_SEQ_NUM
WHERE X_NUM  IN (2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 5 steps

अंतिम हिस्टोग्राम:

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           100     0                   1
998             99600       100     996                 100
3983            298100      100     2981                100
9999            600900      100     6009                100
10000           0           100     0                   1

चलो अनुक्रमिक पूर्णांक के साथ आगे परीक्षण करते हैं लेकिन तालिका में अधिक पंक्तियों के साथ। ध्यान दें कि एक नमूना आकार को मैन्युअल रूप से निर्दिष्ट करने वाली तालिकाओं का कोई प्रभाव नहीं होगा, इसलिए मैं प्रत्येक प्रविष्टि में 100 पंक्तियों को जोड़ूंगा और 1 मिलियन पंक्तियों तक हर बार आंकड़े इकट्ठा करूंगा। मुझे पहले जैसा ही पैटर्न दिखाई देता है, एक बार जब मैं तालिका में 637300 पंक्तियों को छोड़ देता हूं तो मैं डिफ़ॉल्ट नमूना दर के साथ तालिका में 100% पंक्तियों का नमूना नहीं लेता हूं। जैसा कि मैंने पंक्तियाँ हासिल की हैं हिस्टोग्राम के चरणों की संख्या बढ़ जाती है। शायद इसका कारण यह है कि SQL सर्वर डेटा में अधिक अंतराल के साथ समाप्त होता है क्योंकि तालिका में अपरिवर्तित पंक्तियों की संख्या बढ़ जाती है। मैं 1 M पंक्तियों पर 200 कदम भी नहीं मारता, लेकिन अगर मैं उन पंक्तियों को जोड़ता रहा तो मुझे उम्मीद है कि मैं वहां पहुंच जाऊंगा और अंततः नीचे जाना शुरू कर दूंगा।

ग्राफ 2

एक्स-एक्सिस तालिका में पंक्तियों की संख्या है। जैसा कि पंक्तियों की संख्या बढ़ जाती है पंक्तियों का नमूना थोड़ा भिन्न होता है और 650k से अधिक नहीं होता है।

अब VARCHAR डेटा के साथ कुछ सरल परीक्षण करते हैं।

CREATE TABLE X_SEQ_STR (X_STR VARCHAR(5));
CREATE STATISTICS X_SEQ_STR ON X_SEQ_STR(X_STR);

यहां मैं NULL के साथ 200 नंबर (स्ट्रिंग्स के रूप में) डाल रहा हूं।

INSERT INTO X_SEQ_STR
SELECT N FROM dbo.GetNums(200)
UNION ALL
SELECT NULL;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 111 steps, RANGE_ROWS is 0 or 1 for all steps

ध्यान दें कि तालिका में पाए जाने पर NULL को हमेशा अपना हिस्टोग्राम कदम मिलता है। SQL सर्वर मुझे सभी सूचनाओं को संरक्षित करने के लिए ठीक 201 कदम दे सकता था लेकिन ऐसा नहीं किया। तकनीकी रूप से जानकारी खो गई है क्योंकि '1111' उदाहरण के लिए '1' और '2' के बीच है।

अब केवल पूर्णांकों के बजाय विभिन्न वर्णों को सम्मिलित करने का प्रयास करते हैं:

truncate table X_SEQ_STR;

INSERT INTO X_SEQ_STR
SELECT CHAR(10 + N) FROM dbo.GetNums(200)
UNION ALL
SELECT NULL;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 95 steps, RANGE_ROWS is 0 or 1 or 2

अंतिम परीक्षा से कोई वास्तविक अंतर नहीं।

अब पात्रों को सम्मिलित करने का प्रयास करते हैं, लेकिन तालिका में प्रत्येक वर्ण की विभिन्न संख्याएँ डालते हैं। उदाहरण के लिए, CHAR(11)1 पंक्ति है, CHAR(12)2 पंक्तियाँ हैं, आदि।

truncate table X_SEQ_STR;

DECLARE
@loop_num INT;

BEGIN
    SET NOCOUNT ON;

    SET @loop_num = 0;
    WHILE @loop_num < 200
    BEGIN
        SET @loop_num = @loop_num + 1;

        INSERT INTO X_SEQ_STR WITH (TABLOCK)
        SELECT CHAR(10 + @loop_num) FROM dbo.GetNums(@loop_num);
    END;
END;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 148 steps, most with RANGE_ROWS of 0

जैसा कि पहले मैं अभी भी ठीक से 200 हिस्टोग्राम कदम नहीं मिलता है। हालाँकि, कई चरणों RANGE_ROWSमें 0 है।

अंतिम परीक्षण के लिए, मैं प्रत्येक लूप में 5 वर्णों का एक यादृच्छिक स्ट्रिंग सम्मिलित करने जा रहा हूं और प्रत्येक बार आंकड़े एकत्रित करूंगा। यहाँ कोड यादृच्छिक स्ट्रिंग है:

char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))

यहाँ तालिका बनाम हिस्टोग्राम चरणों में पंक्तियों का ग्राफ दिया गया है: ग्राफ 3

ध्यान दें कि एक बार ऊपर और नीचे जाने पर चरणों की संख्या 100 से कम नहीं होती है। मैंने कहीं से सुना है (लेकिन अभी इसे स्रोत नहीं बना सकता है) कि SQL सर्वर हिस्टोग्राम बिल्डिंग एल्गोरिथ्म हिस्टोग्राम चरणों को जोड़ती है क्योंकि यह उनके लिए कमरे से बाहर चलता है। तो आप बस थोड़ा डेटा जोड़कर चरणों की संख्या में भारी बदलाव के साथ समाप्त कर सकते हैं। यहाँ डेटा का एक नमूना है जो मुझे दिलचस्प लगा:

ROWS_IN_TABLE   ROWS_SAMPLED    STEPS
36661           36661           133
36662           36662           143
36663           36663           143
36664           36664           141
36665           36665           138

यहां तक ​​कि जब नमूना लेते हैं FULLSCAN, तो एक पंक्ति को जोड़कर चरणों की संख्या 10 तक बढ़ा सकते हैं, इसे स्थिर रख सकते हैं, फिर इसे 2 से घटा सकते हैं, फिर इसे 3 से घटा सकते हैं।

हम इस सब से क्या संक्षेप में बता सकते हैं? मैं इसमें से कोई भी साबित नहीं कर सकता, लेकिन ये अवलोकन सही प्रतीत होते हैं:

  • SQL सर्वर हिस्टोग्राम बनाने के लिए एक सामान्य उपयोग एल्गोरिदम का उपयोग करता है। कुछ डेटा वितरणों के लिए हाथ से डेटा का अधिक पूर्ण प्रतिनिधित्व बनाना संभव हो सकता है।
  • यदि तालिका में NULL डेटा है और आँकड़े क्वेरी को ढूँढता है, तो उस NULL डेटा को हमेशा अपना स्वयं का हिस्टोग्राम चरण मिल जाता है।
  • तालिका में पाया जाने वाला न्यूनतम मूल्य RANGE_ROWS= 0 के साथ अपना स्वयं का हिस्टोग्राम कदम होता है ।
  • तालिका में पाया गया अधिकतम मूल्य तालिका में अंतिम होगा RANGE_HI_KEY
  • SQL सर्वर अधिक डेटा के नमूने के रूप में इसे खोजने वाले नए डेटा के लिए जगह बनाने के लिए मौजूदा चरणों को संयोजित करने की आवश्यकता हो सकती है। यदि आप पर्याप्त हिस्टोग्राम को देखते हैं तो आप सामान्य मूल्यों को दोहरा सकते हैं DISTINCT_RANGE_ROWSया के लिए दोहरा सकते हैं RANGE_ROWS। उदाहरण के लिए, 255 RANGE_ROWSऔर DISTINCT_RANGE_ROWSयहां अंतिम परीक्षण मामले के लिए कई बार दिखाता है।
  • सरल डेटा वितरण के लिए आप SQL सर्वर को अनुक्रमिक डेटा को एक हिस्टोग्राम कदम में जोड़ सकते हैं, जिससे जानकारी का कोई नुकसान नहीं होता है। हालाँकि जब डेटा में अंतराल जोड़ते हैं तो हिस्टोग्राम उस तरीके से समायोजित नहीं हो सकता है जैसा आप आशा करते हैं।

यह सब एक समस्या कब है? यह एक समस्या है जब एक क्वेरी हिस्टोग्राम के कारण खराब प्रदर्शन करती है जो क्वेरी ऑप्टिमाइज़र के लिए एक तरह से डेटा वितरण का प्रतिनिधित्व करने में असमर्थ है ताकि अच्छे निर्णय ले सकें। मुझे लगता है कि यह सोचने की प्रवृत्ति है कि अधिक हिस्टोग्राम कदम रखना हमेशा बेहतर होता है और इसके लिए अड़चन तब होती है जब SQL सर्वर लाखों पंक्तियों या अधिक पर हिस्टोग्राम उत्पन्न करता है, लेकिन ठीक 200 या 201 हिस्टोग्राम चरणों का उपयोग नहीं करता है। हालाँकि, मैंने तब भी आँकड़ों की समस्याओं को बहुत देखा है जब हिस्टोग्राम में 200 या 201 चरण होते हैं। हमारा कोई नियंत्रण नहीं है कि SQL सर्वर डेटा ऑब्जेक्ट के लिए कितने हिस्टोग्राम कदम रखता है ताकि मैं इसके बारे में चिंता न करूं। हालाँकि, कुछ कदम हैं जो आप तब उठा सकते हैं जब आप आँकड़ों के मुद्दों के कारण खराब प्रदर्शन वाले प्रश्नों का अनुभव करते हैं। मैं एक अत्यंत संक्षिप्त अवलोकन दूंगा।

पूर्ण रूप से आंकड़े इकट्ठा करना कुछ मामलों में मदद कर सकता है। बहुत बड़ी तालिकाओं के लिए तालिका में पंक्तियों का ऑटो नमूना आकार 1% से कम हो सकता है। कभी-कभी यह कॉलम में डेटा व्यवधान के आधार पर खराब योजनाओं को जन्म दे सकता है। क्रिएट स्टेटिस्टिक्स और अपडेट स्टेटिस्टिक्स के लिए माइक्रोसॉफ़्ट का दस्तावेज़ जितना कहता है:

SAMPLE विशेष मामलों के लिए उपयोगी है, जिसमें डिफ़ॉल्ट नमूनाकरण के आधार पर क्वेरी योजना, इष्टतम नहीं है। ज्यादातर स्थितियों में, SAMPLE को निर्दिष्ट करना आवश्यक नहीं है क्योंकि क्वेरी ऑप्टिमाइज़र पहले से ही नमूने का उपयोग करता है और डिफ़ॉल्ट रूप से महत्वपूर्ण नमूना आकार निर्धारित करता है, जैसा कि उच्च-गुणवत्ता वाले क्वेरी प्लान बनाने के लिए आवश्यक है।

अधिकांश कार्यभार के लिए, एक पूर्ण स्कैन की आवश्यकता नहीं है, और डिफ़ॉल्ट नमूना पर्याप्त है। हालाँकि, कुछ वर्कलोड जो डेटा वितरण में व्यापक रूप से भिन्न होते हैं, उन्हें एक बढ़ा हुआ नमूना आकार या पूर्ण स्कैन की आवश्यकता हो सकती है।

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

एक विभाजन दृश्य का उपयोग करना एक तालिका के लिए 200 से अधिक चरणों को प्रभावी ढंग से प्राप्त करने का एक तरीका है। मान लीजिए कि आप प्रति वर्ष एक बड़ी तालिका को आसानी से एक तालिका में विभाजित कर सकते हैं। आप एक ऐसा UNION ALLदृश्य बनाते हैं जो सभी वार्षिक तालिकाओं को जोड़ता है। प्रत्येक टेबल का अपना हिस्टोग्राम होगा। ध्यान दें कि SQL सर्वर 2014 में पेश किए गए नए वृद्धिशील आंकड़े केवल आंकड़ों को अधिक कुशल बनाने की अनुमति देते हैं। क्वेरी ऑप्टिमाइज़र उन आंकड़ों का उपयोग नहीं करेगा जो विभाजन के अनुसार बनाए गए हैं।

कई और परीक्षण हैं जो यहां चलाए जा सकते हैं, इसलिए मैं आपको प्रयोग करने के लिए प्रोत्साहित करता हूं। मैंने एसक्यूएल सर्वर 2014 एक्सप्रेस पर यह परीक्षण किया था इसलिए वास्तव में आपको कुछ भी नहीं रोक रहा है।


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