यकीन नहीं है कि यह बग है, प्रति से लेकिन यह निश्चित रूप से एक दिलचस्प घटना है। SQL सर्वर 2014 में ऑनलाइन पार्टीशन नए हैं इसलिए इसके साथ सॉर्ट करने के लिए कुछ इंटर्नल हो सकते हैं।
यहाँ आपके लिए मेरी सबसे अच्छी व्याख्या है। वृद्धिशील आँकड़ों की बिल्कुल आवश्यकता होती है कि सभी विभाजनों को एक ही दर पर नमूना लिया जाए ताकि जब इंजन आँकड़ों के पृष्ठों को मिला दे तो यह आश्वस्त हो सके कि सैंपल वितरण तुलनीय है। REBUILD
100% नमूना दर पर आवश्यक डेटा के नमूने। इस बात की कोई गारंटी नहीं है कि विभाजन 9 पर 100% नमूना दर हमेशा विभाजन के बाकी हिस्सों की सटीक नमूना दर होगी। इस वजह से, ऐसा प्रतीत होता है कि इंजन नमूने को मर्ज नहीं कर सकता है और आप खाली आँकड़ों के साथ समाप्त हो जाते हैं। हालाँकि, सांख्यिकी वस्तु अभी भी है:
select
check_time = sysdatetime(),
schema_name = sh.name,
table_name = t.name,
stat_name = s.name,
index_name = i.name,
stats_column = index_col(quotename(sh.name)+'.'+quotename(t.name),s.stats_id,1),
s.stats_id,
s.has_filter,
s.is_incremental,
s.auto_created,
sp.last_updated,
sp.rows,
sp.rows_sampled,
sp.unfiltered_rows,
modification_counter
from sys.stats s
join sys.tables t
on s.object_id = t.object_id
join sys.schemas sh
on t.schema_id = sh.schema_id
left join sys.indexes i
on s.object_id = i.object_id
and s.name = i.name
outer apply sys.dm_db_stats_properties(s.object_id, s.stats_id) sp
where t.name = 'TransactionHistory' and sh.name = 'dbo'
आप किसी भी माध्यम से बूँद भर सकते हैं:
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE;
या
UPDATE STATISTICS dbo.TransactionHistory (IDX_ProductId) WITH RESAMPLE ON PARTITIONS (9);
या आप उस ऑब्जेक्ट का उपयोग करके किसी क्वेरी प्लान के पहले संकलन पर अपडेट करने के लिए AutoStats की प्रतीक्षा कर सकते हैं:
-- look at my creative query
select *
from dbo.TransactionHistory
where TransactionDate = '20140101';
उस सब के बाद, एरिन स्टेलैटो के इस ज्ञानवर्धक पोस्ट ने बताया कि वृद्धिशील आँकड़ों की एक बड़ी कमी के रूप में माना जाने लगा है। उनके विभाजन-स्तरीय डेटा का उपयोग क्वेरी प्लान पीढ़ी में ऑप्टिमाइज़र द्वारा नहीं किया जाता है, वृद्धिशील आँकड़ों के अनुमानित लाभ को कम करता है। तब, वृद्धिशील आँकड़ों का वर्तमान लाभ क्या है? मैं प्रस्तुत करूंगा कि उनकी प्राथमिक उपयोगिता पारंपरिक आंकड़ों की तुलना में उच्चतर दर पर लगातार बड़ी तालिकाओं को नमूना करने की क्षमता में है।
अपने उदाहरण का उपयोग करते हुए, यहां बताया गया है कि चीजें कैसे दिखती हैं:
set statistics time on;
update statistics dbo.TransactionHistory(IDX_ProductId)
with fullscan;
--SQL Server Execution Times:
-- CPU time = 94 ms, elapsed time = 131 ms.
update statistics dbo.TransactionHistory(IDX_ProductId)
with resample on partitions(2);
--SQL Server Execution Times:
-- CPU time = 0 ms, elapsed time = 5 ms.
drop index IDX_ProductId On dbo.TransactionHistory;
CREATE NONCLUSTERED INDEX IDX_ProductId ON dbo.TransactionHistory (ProductId)
WITH (DATA_COMPRESSION = ROW)
ON [PRIMARY]
update statistics dbo.TransactionHistory(IDX_ProductId)
with fullscan;
--SQL Server Execution Times:
-- CPU time = 76 ms, elapsed time = 66 ms.
फुलस्कैन आँकड़े वृद्धिशील आँकड़ों पर अद्यतन करते हैं जिनकी लागत 131 मि। फुलस्कैन सांख्यिकी गैर-संरेखित संरेखित लागत 66 एमएस पर अद्यतन करती है। गैर-संरेखित आँकड़ा धीमी गति से ओवरहेड होने के कारण अलग-अलग आँकड़ों के साथ मुख्य हिस्टोग्राम में वापस आ जाता है।। हालांकि, विभाजन-संरेखित सांख्यिकीय ऑब्जेक्ट का उपयोग करके, हम एक विभाजन को अपडेट कर सकते हैं और इसे 5 एमएस में मुख्य हिस्टोग्राम बूँद में विलय कर सकते हैं। तो इस बिंदु पर वृद्धिशील के साथ प्रशासक एक निर्णय के साथ सामना किया है। वे केवल अद्यतनों को अद्यतन करके अपने समग्र सांख्यिकी रखरखाव समय को कम कर सकते हैं, पारंपरिक रूप से अद्यतन करने की आवश्यकता होगी, या वे उच्च नमूना दरों के साथ प्रयोग कर सकते हैं जैसे कि वे संभावित रूप से अपनी पिछली रखरखाव समय सीमा के दौरान समान अवधि में अधिक पंक्तियों का नमूना लेते हैं। पूर्व रखरखाव कक्ष में श्वास कक्ष की अनुमति देता है, बाद वाले एक बहुत बड़ी मेज पर एक जगह पर आंकड़े धक्का दे सकते हैं जहां प्रश्नों को कई सटीक आंकड़ों के आधार पर बेहतर योजना मिलती है। यह कोई गारंटी नहीं है और आपका माइलेज अलग हो सकता है।
पाठक देख सकते हैं कि 66 एमएस इस तालिका पर एक दर्दनाक आँकड़े अद्यतन समय नहीं है, इसलिए मैंने स्टैकएक्सचेंज डेटा सेट पर एक परीक्षण स्थापित करने की कोशिश की। हाल ही में जिस डंप को मैंने डाउनलोड किया उसमें 6,418,608 पोस्ट (2012 से स्टैकऑवरफ्लो पोस्ट और मेरी तरफ से सभी पोस्ट को छोड़कर) हैं।
मैंने डेटा को [CreationDate]
इसलिए विभाजित किया है ... डेमो।
यहां कुछ सुंदर मानक परिदृश्यों के लिए कुछ समय दिया गया है (100% - सूचकांक पुनर्निर्माण, डिफ़ॉल्ट - आँकड़े ऑटो-अपडेट या UPDATE STATISTICS
एक निर्दिष्ट नमूना दर के बिना:
- फुलस्कैन के साथ नॉन-इंक्रीमेंटल स्टैटिस्टिक बनाएं: सीपीयू समय = 23500 एमएस, बीता हुआ समय = 22521 एमएस।
- इंक्रीमेंटल स्टैटिस्टिक वेथ फुलस्कैन बनाएं: सीपीयू समय = 20406 एमएस, बीता हुआ समय = 15413 एमएस।
- नॉन-इन्क्रीमेंटल स्टैटिस्टिक को डिफॉल्ट सैंपल रेट के साथ अपडेट करें: सीपीयू समय = 406 एमएस, बीता हुआ समय = 408 एमएस।
- डिफ़ॉल्ट नमूना दर के साथ वृद्धिशील आँकड़ा अपडेट करें: सीपीयू समय = 453 एमएस, बीता हुआ समय = 507 एमएस।
मान लें कि हम इन डिफ़ॉल्ट परिदृश्यों की तुलना में अधिक परिष्कृत हैं और यह तय किया है कि 10% नमूना दर न्यूनतम दर है जो हमें रखरखाव समय को उचित समय सीमा तक रखने के दौरान हमें उन योजनाओं को प्राप्त करना चाहिए जो हमें चाहिए।
- अद्यतन गैर-वृद्धिशील आँकड़ा 10 प्रतिशत के साथ: सीपीयू समय = 2344 एमएस, बीता समय = 2441 एमएस।
- 10 प्रतिशत के नमूने के साथ वृद्धिशील आँकड़ा अपडेट करें: सीपीयू समय = 2344 एमएस, बीता हुआ समय = 2388 एमएस।
अब तक एक वृद्धिशील आँकड़ा होने का कोई स्पष्ट लाभ नहीं है। हालाँकि, यदि हम अनिर्दिष्ट sys.dm_db_stats_properties_internal()
DMV (नीचे) का लाभ उठाते हैं, तो आप कुछ जानकारी प्राप्त कर सकते हैं कि आप किस विभाजन (अपडेट) में अपडेट करना चाहते हैं। मान लें कि हमने विभाजन 3 में डेटा में बदलाव किए हैं और हम चाहते हैं कि आने वाले प्रश्नों के लिए आँकड़े नए हों। यहाँ हमारे विकल्प हैं:
- नॉन-इन्क्रीमेंटल को डिफॉल्ट में अपडेट करें (ऑटो-स्टैट्स अपडेट का डिफ़ॉल्ट व्यवहार भी): 408 एमएस।
- अद्यतन गैर-वृद्धि 10%: 2441 एमएस।
- अद्यतन वृद्धिशील सांख्यिकी, विभाजन 3 विमोचन (10% - हमारी परिभाषित नमूना दर): सीपीयू समय = 63 एमएस, बीता हुआ समय = 63 एमएस।
यहां हमें निर्णय लेने की आवश्यकता है। क्या हम 63 एमएस की जीत लेते हैं। आँकड़ों का विभाजन-आधारित अद्यतन, या हम नमूना दर को और भी अधिक बढ़ाते हैं? मान लीजिए कि हम वृद्धिशील आँकड़ों पर 50% नमूना लेने की प्रारंभिक इच्छा रखते हैं:
- 50% पर वृद्धिशील सांख्यिकी अपडेट करें: बीता हुआ समय = 16840 एमएस।
- अद्यतन वृद्धिशील सांख्यिकी, विभाजन 3 के साथ रीकंप्लस (50% - हमारा नया अपडेट समय): बीता हुआ समय = 295 एमएस।
हम बहुत अधिक डेटा का नमूना लेने में सक्षम हैं, शायद हमारे डेटा के बारे में बेहतर अनुमान लगाने के लिए ऑप्टिमाइज़र की स्थापना कर रहे हैं (भले ही यह विभाजन-स्तरीय आँकड़ों का उपयोग नहीं कर रहा है, फिर भी) और हम इसे और अधिक तेज़ी से करने में सक्षम हैं जो अब हमारे पास है वृद्धिशील सांख्यिकी।
हालांकि यह पता लगाने के लिए एक अंतिम मजेदार बात है। तुल्यकालिक आँकड़े अपडेट के बारे में क्या? जब ऑटोस्टैट्स में किक होती है तब भी 50% नमूना दर संरक्षित होती है?
मैंने विभाजन 3 से डेटा हटा दिया और क्रिएशनडेट पर एक क्वेरी चलाई और फिर उसी क्वेरी के साथ दरों की जाँच की। 50% नमूना दर संरक्षित थी।
तो, लंबी कहानी छोटी: वृद्धिशील सांख्यिकी सही मात्रा में विचार और प्रारंभिक सेटअप कार्य के साथ एक उपयोगी उपकरण हो सकती है। हालाँकि, आपको उस समस्या का पता होना चाहिए जिसे आप हल करने का प्रयास कर रहे हैं और फिर आपको इसके लिए उचित रूप से हल करने की आवश्यकता है। यदि आपको खराब कार्डिनैलिटी का अनुमान है, तो आप रणनीतिक नमूना दर और कुछ निवेशित हस्तक्षेप के साथ बेहतर योजना प्राप्त करने में सक्षम हो सकते हैं। हालाँकि, आपको केवल लाभ का एक छोटा सा हिस्सा मिल रहा है क्योंकि हिस्टोग्राम का उपयोग एकल, मर्ज किए गए आँकड़े पृष्ठ और विभाजन-स्तरीय जानकारी नहीं है। यदि आप अपनी रखरखाव खिड़की में दर्द महसूस कर रहे हैं, तो हो सकता है कि वृद्धिशील आंकड़े आपकी मदद कर सकते हैं, लेकिन संभवतः आपको उच्च-स्पर्श रखरखाव हस्तक्षेप प्रक्रिया स्थापित करने की आवश्यकता होगी। भले ही,:
- इंडेक्स के साथ बनाए गए आंकड़े जो आधार तालिका के साथ विभाजन-संरेखित नहीं होते हैं।
- AlwaysOn पठनीय माध्यमिक डेटाबेस पर बनाए गए आँकड़े।
- रीड-ओनली डेटाबेस पर बनाए गए आंकड़े।
- फ़िल्टर किए गए अनुक्रमित पर बनाए गए आंकड़े।
- आंकड़ों को विचारों पर बनाया गया।
- आंतरिक तालिकाओं पर बनाए गए आँकड़े।
- स्थानिक इंडेक्स या XML इंडेक्स के साथ बनाए गए आंकड़े।
उम्मीद है की यह मदद करेगा
select
sysdatetime(),
schema_name = sh.name,
table_name = t.name,
stat_name = s.name,
index_name = i.name,
leading_column = index_col(quotename(sh.name)+'.'+quotename(t.name),s.stats_id,1),
s.stats_id,
parition_number = isnull(sp.partition_number,1),
s.has_filter,
s.is_incremental,
s.auto_created,
sp.last_updated,
sp.rows,
sp.rows_sampled,
sp.unfiltered_rows,
modification_counter = coalesce(sp.modification_counter, n1.modification_counter)
from sys.stats s
join sys.tables t
on s.object_id = t.object_id
join sys.schemas sh
on t.schema_id = sh.schema_id
left join sys.indexes i
on s.object_id = i.object_id
and s.name = i.name
cross apply sys.dm_db_stats_properties_internal(s.object_id, s.stats_id) sp
outer apply sys.dm_db_stats_properties_internal(s.object_id, s.stats_id) n1
where n1.node_id = 1
and (
(is_incremental = 0)
or
(is_incremental = 1 and sp.partition_number is not null)
)
and t.name = 'Posts'
and s.name like 'st_posts%'
order by s.stats_id,isnull(sp.partition_number,1)