क्या एक पुन: अनुक्रमणिका अद्यतन आँकड़े बनाती है?


43

मैं पिछले हफ्ते MS10775A कोर्स कर रहा हूं और एक सवाल जो सामने आया है कि ट्रेनर जवाब नहीं दे सकता है वह है:

क्या री-इंडेक्स आँकड़ों को अपडेट करता है?

हमने ऑनलाइन चर्चा में पाया कि दोनों ऐसा करते हैं और यह नहीं करता है।


यह ध्यान रखना उपयोगी है कि REINDEXअनुक्रमणिका के पुनर्निर्माण के साइड-इफेक्ट के रूप में कॉलम के आँकड़े को अपडेट करता है - आपको आंकड़ों को अपडेट करने की आवश्यकता नहीं है । तालिका में डेटा नहीं बदलता है। यह एक ही डेटा है, यह केवल क) यह कताई थाली (जब एक पृष्ठ पुनर्गठित होता है), या बी) पर एक अलग पृष्ठ (फिर से निर्माण के मामले में) में स्थित है। तो: एक फिर से सूचकांक करता है अद्यतन (कुछ) आँकड़े: कोई वहाँ की जरूरत है यह करने के लिए।
इयान बॉयड

जवाबों:


51

आप अपडेट के आंकड़ों की देखभाल करते समय निम्नलिखित बातों को ध्यान में रख सकते हैं ( पुनर्निर्माण इंडेक्स बनाम अपडेटिंग स्टेटिस्टिक्स से कॉपी किए गए हैं (बेंजामिन नेवरेज)

  1. डिफ़ॉल्ट रूप से, UPDATE STATISTICSबयान केवल तालिका के रिकॉर्ड का एक नमूना का उपयोग करता है। इस्तेमाल UPDATE STATISTICS WITH FULLSCANकरने से पूरी टेबल स्कैन हो जाएगी।

  2. डिफ़ॉल्ट रूप से, UPDATE STATISTICSस्टेटमेंट इंडेक्स और कॉलम दोनों आँकड़ों को अपडेट करता है। COLUMNSविकल्प का उपयोग करने से कॉलम के आँकड़े केवल अपडेट होंगे। INDEXविकल्प का उपयोग करने से सूचकांक के आंकड़े ही अपडेट होंगे।

  3. अनुक्रमणिका का पुनर्निर्माण करना , उदाहरण के लिए उपयोग करके तालिका के विभाजन होने तकALTER INDEX … REBUILD उपयोग के समतुल्य के साथ सूचकांक आँकड़ों को भी अद्यतन किया जाएगा , जिस स्थिति में आँकड़ों का केवल नमूना लिया जाता है (SQL सर्वर 2012 और बाद में लागू होता है)।WITH FULLSCAN

  4. मैन्युअल रूप से उपयोग किए जाने वाले आंकड़े CREATE STATISTICSकिसी भी ALTER INDEX ... REBUILDऑपरेशन द्वारा अपडेट नहीं किए जाते हैं , जिसमें शामिल हैं ALTER TABLE ... REBUILDALTER TABLE ... REBUILDयदि एक तालिका को फिर से बनाया जा रहा है, तो एक निर्धारित सूचकांक के लिए अद्यतन आँकड़े हैं।

  5. एक सूचकांक का पुनर्गठन , उदाहरण के लिए ALTER INDEX … REORGANIZEकिसी भी आँकड़े को अद्यतन नहीं करता है।

संक्षिप्त उत्तर यह है कि आपको UPDATE STATISTICSकॉलम आँकड़े अपडेट करने के लिए उपयोग करने की आवश्यकता है और यह कि एक इंडेक्स पुनर्निर्माण केवल इंडेक्स आँकड़े अपडेट करेगा। आप एक तालिका पर सभी आँकड़ों के लिए इंडेक्स-आँकड़े और मैन्युअल रूप से बनाए गए आँकड़ों सहित UPDATE STATISTICS (tablename) WITH FULLSCAN;वाक्यविन्यास के साथ एक अद्यतन को बाध्य कर सकते हैं ।

निम्नलिखित कोड ऊपर वर्णित नियमों को दिखाता है:

सबसे पहले, हम स्तंभों के एक जोड़े के साथ एक तालिका बनाएंगे, और एक गुच्छेदार सूचकांक:

USE tempdb;

IF OBJECT_ID(N'dbo.SomeTable', N'U') IS NOT NULL
DROP TABLE dbo.SomeTable;

CREATE TABLE dbo.SomeTable
(
    rn int NOT NULL IDENTITY(1,1)
        CONSTRAINT pk
        PRIMARY KEY NONCLUSTERED
    , i int NOT NULL INDEX i 
    , d sysname NOT NULL
) ON [PRIMARY] WITH (DATA_COMPRESSION = NONE);

CREATE UNIQUE CLUSTERED INDEX cx ON dbo.SomeTable (i, d);

CREATE STATISTICS d ON dbo.SomeTable (d) WITH FULLSCAN;

INSERT INTO dbo.SomeTable (d, i)
SELECT c1.name, c1.id
FROM sys.syscolumns c1;

यह क्वेरी उस तारीख को दिखाती है जब प्रत्येक आँकड़े ऑब्जेक्ट को अंतिम बार अपडेट किया गया था:

SELECT ObjectName = sc.name + N'.' + o.name
    , StatsName = s.name
    , StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
    INNER JOIN sys.objects o ON s.object_id = o.object_id
    INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
    AND o.name = N'SomeTable';

परिणाम दिखाते हैं कि अभी तक कोई अपडेट नहीं हुआ है, जो सही है क्योंकि हमने अभी तालिका बनाई है:

╔═══════════════╦═══════════╦═══════════╗
║ ObjectName ats StatsName D StatsDate ║
╠═══════════════╬═══════════╬═══════════╣
║ dbo.SomeTable x cx ║ NULL ome
║ dbo.SomeTable ║ i ║ NULL ome
║ dbo.SomeTable ║ pk ║ NULL ome
║ dbo.SomeTable ║ d ║ NULL ome
╚═══════════════╩═══════════╩═══════════╝

आइए पूरी तालिका का पुनर्निर्माण करें, और देखें कि क्या आँकड़े अद्यतन हैं:

ALTER TABLE dbo.SomeTable REBUILD;

SELECT ObjectName = sc.name + N'.' + o.name
    , StatsName = s.name
    , StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
    INNER JOIN sys.objects o ON s.object_id = o.object_id
    INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
    AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ats StatsName D StatsDate ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable x cx -09 2018-09-17 14: 09: 13.590 ome
║ dbo.SomeTable ║ i ║ NULL ome
║ dbo.SomeTable ║ pk ║ NULL ome
║ dbo.SomeTable ║ d ║ NULL ome
╚═══════════════╩═══════════╩═════════════════════ ════╝

परिणाम केवल संकुल अनुक्रमणिका आँकड़े अद्यतन किए गए थे।

अगला, हम असतत UPDATE STATSसंचालन करते हैं:

UPDATE STATISTICS dbo.SomeTable(d) WITH FULLSCAN;

SELECT ObjectName = sc.name + N'.' + o.name
    , StatsName = s.name
    , StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
    INNER JOIN sys.objects o ON s.object_id = o.object_id
    INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
    AND o.name = N'SomeTable';

जैसा कि आप देख सकते हैं, हमने dकॉलम पर केवल आँकड़े अपडेट किए हैं :

╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ats StatsName D StatsDate ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable x cx -09 2018-09-17 14: 09: 13.590 ome
║ dbo.SomeTable ║ i ║ NULL ome
║ dbo.SomeTable ║ pk ║ NULL ome
║ dbo.SomeTable ║ d -09 2018-09-17 14: 09: 13.597 ome
╚═══════════════╩═══════════╩═════════════════════ ════╝

अब, हम संपूर्ण तालिका पर आँकड़े अपडेट करेंगे:

UPDATE STATISTICS dbo.SomeTable WITH FULLSCAN;

SELECT ObjectName = sc.name + N'.' + o.name
    , StatsName = s.name
    , StatsDate = STATS_DATE(s.object_id, s.stats_id)
FROM sys.stats s
    INNER JOIN sys.objects o ON s.object_id = o.object_id
    INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id
WHERE sc.name = N'dbo'
    AND o.name = N'SomeTable';
╔═══════════════╦═══════════╦═════════════════════ ════╗
║ ObjectName ats StatsName D StatsDate ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
║ dbo.SomeTable x cx -09 2018-09-17 14: 09: 13.600 ome
║ dbo.SomeTable ║ i -09 2018-09-17 14: 09: 13.600 ome
║ dbo.SomeTable ║ pk -09 2018-09-17 14: 09: 13.603 ome
║ dbo.SomeTable ║ d -09 2018-09-17 14: 09: 13.607 ome
╚═══════════════╩═══════════╩═════════════════════ ════╝

जैसा कि आप देख सकते हैं, सभी आँकड़ों को अपडेट करने का एकमात्र तरीका यह है कि या तो प्रत्येक को मैन्युअल रूप से अपडेट किया जाए, या संपूर्ण तालिका को अपडेट किया जाए UPDATE STATISTICS (table);


@JeremyWeir - जैसा कि आप उदाहरण कोड से देख सकते हैं, जो मैंने अभी ऊपर दिए गए प्रश्न में जोड़ा है, केवल अपडेट किए गए आंकड़े स्पष्ट रूप से या तो ALTER INDEX ... REBUILDएक UPDATE STATISTICSबयान के माध्यम से अपडेट किए जाते हैं । यदि तालिका स्वयं ही बनाई गई है, तो केवल संकुल अनुक्रमणिका आँकड़े अद्यतन किए जाते हैं। FYI, प्राथमिक कुंजी और क्लस्टर इंडेक्स आवश्यक रूप से समान इंडेक्स ऑब्जेक्ट द्वारा समर्थित नहीं हैं।
मैक्स वर्नोन

5

SQL सर्वर आँकड़े राज्यों के लिए Microsoft डॉक्स पृष्ठ :

पुन: निर्माण, डीफ़्रैग्मेंटिंग या किसी इंडेक्स को फिर से व्यवस्थित करने जैसे ऑपरेशन डेटा के वितरण को नहीं बदलते हैं। इसलिए, आपको ALTER INDEX REBUILD, DBCC DBREINDEX, DBCC INDEXDEFRAG, या ALTER INDEX REORGANIZE संचालन करने के बाद आँकड़े अपडेट करने की आवश्यकता नहीं है । क्वेरी ऑप्टिमाइज़र आँकड़े को तब अद्यतन करता है जब आप किसी तालिका पर अनुक्रमणिका का पुनर्निर्माण करते हैं या ALTER INDEX REBUILD या DBCC DBREINDEX के साथ देखते हैं, हालाँकि यह आँकड़ों का अद्यतन अनुक्रमणिका को फिर से बनाना है। क्वेरी ऑप्टिमाइज़र DBCC INDEXDEFRAG या ALTER INDEX REORGANIZE संचालन के बाद के आँकड़े अपडेट नहीं करता है।

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