क्या मुझे डेटा वेयरहाउसिंग परिदृश्य में "ऑटो अपडेट आँकड़े" को अक्षम करना चाहिए?


12

मेरे पास SQL ​​Server में 200 GB डेटा वेयरहाउस है।

मैं कुछ प्रश्नों के लिए वास्तव में धीमी गति से निष्पादन का समय अनुभव कर रहा हूं; उदाहरण के लिए 12 घंटे के साथ एक साधारण deleteक्वेरी के लिए inner join

निष्पादन योजनाओं के साथ कुछ शोध करने के बाद, मैंने WITH FULLSCANविकल्प का उपयोग करके क्वेरी में शामिल 2 तालिकाओं के आंकड़ों को अपडेट किया है।

क्वेरी अब एक सेकंड से भी कम समय में निष्पादित होती है, इसलिए ऐसा प्रतीत होता है कि आँकड़े अद्यतित नहीं थे।

मैं auto update statisticsडेटाबेस पर अक्षम करने और UPDATE STATISTICSडेटा वेयरहाउस लोड होने के बाद मैन्युअल रूप से चलाने पर विचार कर रहा हूं । डेटा वेयरहाउस को रात में एक स्रोत ईआरपी सिस्टम से दैनिक रूप से लोड किया जाता है।

क्या मैं auto update statisticsडेटा वेयरहाउसिंग परिदृश्यों को संभालने में सही हूं, वास्तव में उपयोगी नहीं है? इसके बजाय, डेटा लोड होने के बाद आंकड़ों को मैन्युअल रूप से अपडेट करने के लिए यह अधिक समझ में आता है?


आँकड़ों के बारे में यह एक बहुत अच्छी रीडिंग है: simple-talk.com/sql/performance/… हम 1TB db पर आँकड़ों को अपडेट करने के लिए Ola के समाधान ola.hallengren.com/… का उपयोग करके एक दैनिक नौकरी भी चला रहे हैं । मैं ऑटो अपडेट आँकड़े विकल्प को अक्षम नहीं करूंगा।
जॉय वॉकर

1
यह इस बात पर बहुत निर्भर करता है कि आपकी तालिका में कितने रिकॉर्ड हैं और आप एक बैच में कितना जोड़ते हैं। 1 बी पंक्ति तालिका में जहां आप एक रात में 20 मीटर पंक्तियों को जोड़ते हैं, आपके आंकड़े हर 10 दिनों के बारे में अपडेट किए जाएंगे जो महान नहीं है।
JNK

2
बस FYI - 20% से एक गतिशील प्रतिशत दर से आँकड़ों के अद्यतन के लिए सीमा को बदलने के लिए एक ट्रेस ध्वज (2371) है। यहाँ और देखें: blogs.msdn.com/b/saponsqlserver/archive/2011/09/07/…
DaniSQL

बहुत जानकारीपूर्ण लिंक, धन्यवाद! @ जेएनके: हां, यह एक बड़ा डीबी है। मंचन तालिका में 300 मी + पंक्तियाँ हैं और दिन के आधार पर हम प्रतिदिन 1 मी से 10 मी तक कुछ डाल रहे हैं। आंकड़ों पर अधिक बारीकी से विचार करेंगे, क्योंकि यह नीचे दिए गए उत्तर द्वारा प्रस्तावित किया गया था।
सासो

जवाबों:


11

यहां ऑटोप्‍पूलेट ऑफ स्‍टेटस होने पर व्‍हाइटपेपर होता है । यहाँ आँकड़ों के लिए मुख्य बिंदुओं के लिए स्वत: अपडेट दिए गए हैं:

  • तालिका का आकार 0 से> 0 पंक्तियों (परीक्षण 1) से चला गया है।
  • तालिका में पंक्तियों की संख्या जब आँकड़े एकत्र किए गए थे 500 या उससे कम थे, और तब से वस्तु ऑब्जेक्ट के प्रमुख स्तंभ का कोलमोड्रक्ट 500 से अधिक बदल गया है (परीक्षण 2)।
  • तालिका में आंकड़े एकत्रित होने पर 500 से अधिक पंक्तियाँ थीं, और आँकड़ों के प्रमुख स्तंभ का कोलमोड्रर तालिका में पंक्तियों की संख्या के 500 + 20% से अधिक बदल गया है जब आंकड़े एकत्र किए गए थे (परीक्षण 3) ।

तो @JNK ने एक टिप्पणी में कहा कि यदि आपके पास एक तालिका में 1 बिलियन पंक्तियाँ हैं, तो आपको अपडेट को ट्रिगर करने के लिए आंकड़े में पहले कॉलम में 20,000,5000 लिखना होगा।

चलो निम्नलिखित संरचना लेते हैं:

CREATE TABLE dbo.test_table (
    test_table_id INTEGER IDENTITY(1,1) NOT NULL, 
    test_table_value VARCHAR(50), 
    test_table_value2 BIGINT, 
    test_table_value3 NUMERIC(10,2)
);

CREATE CLUSTERED INDEX cix_test_table ON dbo.test_table (test_table_id, test_table_value);

अब हम यह देखने के लिए जांच कर सकते हैं कि सांख्यिकी भूमि में क्या हुआ।

select * 
    from sys.stats
        where object_id = OBJECT_ID('dbo.test_table')

stat_container

हालाँकि, यह देखने के लिए कि क्या यह एक सार्थक सांख्यिकीय वस्तु है जिसकी हमें आवश्यकता है:

dbcc show_statistics('dbo.test_table',cix_test_table)

हिस्टोग्राम

इसलिए इस आंकड़े को अपडेट नहीं किया गया है। ऐसा इसलिए है क्योंकि ऐसा लगता है कि आँकड़ा SELECTतब तक अद्यतन नहीं होता है और तब भी SELECTSQL सर्वर के अपने हिस्टोग्राम के बाहर पड़ना पड़ता है। यहाँ एक परीक्षण स्क्रिप्ट है कि मैं यह परीक्षण करने के लिए दौड़ा:

    CREATE TABLE test_table (
        test_table_id INTEGER IDENTITY(1,1) NOT NULL, 
        test_table_value VARCHAR(50), 
        test_table_value2 BIGINT, 
        test_table_value3 NUMERIC(10,2)
    );

    CREATE CLUSTERED INDEX cix_test_table ON test_table (test_table_id, test_table_value);

    ALTER TABLE test_table ADD CONSTRAINT pk_test_table PRIMARY KEY  (test_table_id)

    SELECT * 
        FROM sys.stats
            WHERE object_id = OBJECT_ID('dbo.test_table')

    --DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table)
    DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;

declare @test int = 0

WHILE @test < 1
    BEGIN
        INSERT INTO test_table (test_table_value,test_table_value2,test_table_value3) VALUES
            ('stats test' + CAST(@test AS VARCHAR(10)),@test, @test)
        SET @test = @test + 1;
    END

SELECT 'one row|select < 1', * FROM test_table WHERE test_table_id < 1;
--DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table);
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;

SET @test = 1

WHILE @test < 500
    BEGIN
        INSERT INTO test_table (test_table_value,test_table_value2,test_table_value3) VALUES
            ('stats test' + CAST(@test AS VARCHAR(10)),@test, @test)
        SET @test = @test + 1;
    END

SELECT '100 rows(add 99)|select < 100',* FROM test_table WHERE test_table_id < 100;
--DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table);
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;
--get the table up to 500 rows/changes
WHILE @test < 500
    BEGIN
        INSERT INTO test_table (test_table_value,test_table_value2,test_table_value3) VALUES
            ('stats test' + CAST(@test AS VARCHAR(10)),@test, @test)
        SET @test = @test + 1;
    END
SELECT '500 rows(add 400)|select < 100',* FROM test_table WHERE test_table_id < 100;
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;
SELECT '500 rows(add 400)|select < 500',* FROM test_table WHERE test_table_id < 500;
--DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table);
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;
--bump it to 501
SET @test = 500;
WHILE @test < 501
    BEGIN
        INSERT INTO test_table (test_table_value,test_table_value2,test_table_value3) VALUES
            ('stats test' + CAST(@test AS VARCHAR(10)),@test, @test)
        SET @test = @test + 1;
    END


SELECT '501 rows(add 1)|select < 501',* FROM test_table WHERE test_table_id < 501;
--DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table);
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;

--bump it to 600
SET @test = 501;
WHILE @test < 600
    BEGIN
        INSERT INTO test_table (test_table_value,test_table_value2,test_table_value3) VALUES
            ('stats test' + CAST(@test AS VARCHAR(10)),@test, @test)
        SET @test = @test + 1;
    END

SELECT '600 rows (add 100)|select < 600',* FROM test_table WHERE test_table_id < 600;
--DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table);
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;

--bump it to 700
SET @test = 600;
WHILE @test < 700
    BEGIN
        INSERT INTO test_table (test_table_value,test_table_value2,test_table_value3) VALUES
            ('stats test' + CAST(@test AS VARCHAR(10)),@test, @test)
        SET @test = @test + 1;
    END

SELECT '700 rows (add 100)|select < 700', * FROM test_table WHERE test_table_id < 700;
--DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table);
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;

--bump it to 1200
SET @test = 700;
WHILE @test < 1200
    BEGIN
        INSERT INTO test_table (test_table_value,test_table_value2,test_table_value3) VALUES
            ('stats test' + CAST(@test AS VARCHAR(10)),@test, @test)
        SET @test = @test + 1;
    END

SELECT '1200 rows (add 500)|select < 1200',* FROM test_table WHERE test_table_id < 1200;
--DBCC SHOW_STATISTICS('dbo.test_table',pk_test_table);
DBCC SHOW_STATISTICS('dbo.test_table',cix_test_table) WITH STAT_HEADER;
--DROP TABLE test_table

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

तिरछे विश्लेषण के लिए आपको उस विशेष स्टेट / इंडेक्स संयोजन पर DBCC SHOW_STATISTICS(<stat_object>, <index_name>);(जिसके बिना उपरोक्त स्क्रिप्ट में WITH STAT_HEADER) चलाने की आवश्यकता है जिसे आप जांचना चाहते हैं। अपने तिरछी नज़र को हटाने का एक त्वरित तरीका हिस्टोग्राम (तीसरा परिणाम सेट) को देखना और अपने में विचरण की जाँच करना होगा EQ_ROWS। यदि यह काफी सुसंगत है तो आपका तिरछा न्यूनतम है। इसे ऊपर ले जाने के लिए, आप RANGE_ROWSकॉलम को देखते हैं और वहाँ विचरण को देखते हैं क्योंकि यह मापता है कि प्रत्येक चरण के बीच कितनी पंक्तियाँ मौजूद हैं। अंत में, आप (दूसरे परिणाम सेट) [All density]से परिणाम ले सकते हैं DENSITY_VECTORऔर उस [Rows Sampled]मूल्य में STAT_HEADER(पहले परिणाम सेट) से गुणा कर सकते हैं और देख सकते हैं कि उस कॉलम पर क्वेरी के लिए औसत अपेक्षा क्या होगी। आप उस औसत की तुलना अपने से करते हैंEQ_ROWS और अगर कई जगह हैं जहां यह काफी भिन्न होता है, तो आप तिरछा हो गए हैं।

यदि आप पाते हैं कि आपके पास तिरछा है, तो आपको उन सीमाओं पर कुछ फ़िल्टर्ड आँकड़े बनाने पर विचार करने की ज़रूरत है जो बहुत अधिक हैं RANGE_ROWSताकि आप उन मूल्यों पर बेहतर अनुमानों के लिए एक अतिरिक्त कदम दे सकें।

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


व्यापक उत्तर के लिए धन्यवाद। मेरे पास आंकड़ों के साथ उतना अनुभव नहीं है और जैसा कि मैंने सोचा था कि यह अधिक मुश्किल प्रतीत होता है। निश्चित रूप से करीब से देखने और अपने दिशानिर्देशों का पालन करेंगे।
सासो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.