पृष्ठभूमि
आंकड़े ऑब्जेक्ट के लिए डेटा फॉर्म के एक बयान का उपयोग करके इकट्ठा किए जाते हैं:
SELECT
StatMan([SC0], [SC1], [SB0000])
FROM
(
SELECT TOP 100 PERCENT
[SC0], [SC1], STEP_DIRECTION([SC0]) OVER (ORDER BY NULL) AS [SB0000]
FROM
(
SELECT
[TextValue] AS [SC0],
[Id] AS [SC1]
FROM [dbo].[Test]
TABLESAMPLE SYSTEM (2.223684e+001 PERCENT)
WITH (READUNCOMMITTED)
) AS _MS_UPDSTATS_TBL_HELPER
ORDER BY
[SC0],
[SC1],
[SB0000]
) AS _MS_UPDSTATS_TBL
OPTION (MAXDOP 1)
आप इस स्टेटमेंट को एक्सटेंडेड इवेंट्स या प्रोफाइलर ( SP:StmtCompleted
) के साथ इकट्ठा कर सकते हैं ।
सांख्यिकी जेनरेशन क्वेरीज़ अक्सर बेस टेबल (नॉनक्लेस्टेड इंडेक्स के बजाय) को उन मूल्यों की क्लस्टरिंग से बचने के लिए एक्सेस करते हैं जो स्वाभाविक रूप से नॉनक्लेस्टेड इंडेक्स पेजों पर होते हैं।
नमूने की पंक्तियों की संख्या नमूने लेने के लिए चुने गए पूरे पृष्ठों की संख्या पर निर्भर करती है। तालिका का प्रत्येक पृष्ठ या तो चयनित है या यह नहीं है। चयनित पृष्ठों की सभी पंक्तियाँ आँकड़ों में योगदान करती हैं।
रैंडम नंबर
SQL सर्वर यह तय करने के लिए एक यादृच्छिक संख्या जनरेटर का उपयोग करता है कि पृष्ठ योग्य है या नहीं। इस उदाहरण में इस्तेमाल किया गया जनरेटर लीमर यादृच्छिक संख्या जनरेटर है जिसमें पैरामीटर मान नीचे दिखाए गए हैं:
X अगला = X बीज * 7 5 मॉड (2 31 - 1)
के मूल्य की गणना निम्न के योग के रूप में की जाती है:Xseed
निम्न bigint
तालिका का पूर्णांक भाग ( ) बेस टेबल के partition_id
उदा
SELECT
P.[partition_id] & 0xFFFFFFFF
FROM sys.partitions AS P
WHERE
P.[object_id] = OBJECT_ID(N'dbo.Test', N'U')
AND P.index_id = 1;
REPEATABLE
क्लॉज में निर्दिष्ट मूल्य
- नमूना के लिए
UPDATE STATISTICS
, REPEATABLE
मान 1 है।
m_randomSeed
निष्पादन मान में आंतरिक विधि डीबगिंग जानकारी के तत्व में यह मान उजागर होता है, जब ट्रेस ध्वज 8666 सक्षम होता है, उदाहरण के लिए<Field FieldName="m_randomSeed" FieldValue="1" />
SQL Server 2012 के लिए, यह गणना निम्न में होती है sqlmin!UnOrderPageScanner::StartScan
:
mov edx,dword ptr [rcx+30h]
add edx,dword ptr [rcx+2Ch]
जहाँ मेमोरी में [rcx+30h]
विभाजन आईडी के कम 32 बिट्स [rcx+2Ch]
होते हैं और मेमोरी REPEATABLE
में उपयोग में मूल्य होता है ।
यादृच्छिक संख्या जनरेटर को बाद में उसी तरीके से शुरू किया जाता है, कॉलिंग sqlmin!RandomNumGenerator::Init
, जहां निर्देश:
imul r9d,r9d,41A7h
... 41A7
हेक्स द्वारा बीज को गुणा करता है (16807 दशमलव = 7 5 ) जैसा कि ऊपर समीकरण में दिखाया गया है।
बाद में यादृच्छिक संख्या (अलग-अलग पृष्ठों के लिए) एक ही मूल कोड का उपयोग करके उत्पन्न की जाती है sqlmin!UnOrderPageScanner::SetupSubScanner
।
StatMan
StatMan
ऊपर दिखाए गए उदाहरण क्वेरी के लिए, टी-एसक्यूएल स्टेटमेंट के लिए उन्हीं पृष्ठों को एकत्र किया जाएगा:
SELECT
COUNT_BIG(*)
FROM dbo.Test AS T
TABLESAMPLE SYSTEM (2.223684e+001 PERCENT) -- Same sample %
REPEATABLE (1) -- Always 1 for statman
WITH (INDEX(0)); -- Scan base object
यह निम्न के आउटपुट से मेल खाएगा:
SELECT
DDSP.rows_sampled
FROM sys.stats AS S
CROSS APPLY sys.dm_db_stats_properties(S.[object_id], S.stats_id) AS DDSP
WHERE
S.[object_id] = OBJECT_ID(N'dbo.Test', N'U')
AND S.[name] = N'IX_Test_TextValue';
किनारे का मामला
MINSTD लेहमर रैंडम नंबर जनरेटर का उपयोग करने का एक परिणाम यह है कि बीज मान शून्य और int.max का उपयोग नहीं किया जाना चाहिए क्योंकि यह एल्गोरिथ्म में जीरो के अनुक्रम (प्रत्येक पृष्ठ का चयन) का उत्पादन करेगा।
कोड शून्य का पता लगाता है, और उस स्थिति में बीज के रूप में सिस्टम 'क्लॉक' से एक मान का उपयोग करता है। यदि बीज int.max ( 0x7FFFFFFF
= 2 31 - 1) है तो यह ऐसा नहीं करता है ।
हम इस परिदृश्य को इंजीनियर कर सकते हैं क्योंकि प्रारंभिक बीज की गणना विभाजन आईडी के कम 32 बिट्स और REPEATABLE
मूल्य के योग के रूप में की जाती है । वह REPEATABLE
मान जिसके परिणामस्वरूप बीज int.max होगा और इसलिए प्रत्येक पृष्ठ को नमूने के लिए चुना जा रहा है:
SELECT
0x7FFFFFFF - (P.[partition_id] & 0xFFFFFFFF)
FROM sys.partitions AS P
WHERE
P.[object_id] = OBJECT_ID(N'dbo.Test', N'U')
AND P.index_id = 1;
एक पूर्ण उदाहरण में कार्य करना:
DECLARE @SQL nvarchar(4000) =
N'
SELECT
COUNT_BIG(*)
FROM dbo.Test AS T
TABLESAMPLE (0 PERCENT)
REPEATABLE (' +
(
SELECT TOP (1)
CONVERT(nvarchar(11), 0x7FFFFFFF - P.[partition_id] & 0xFFFFFFFF)
FROM sys.partitions AS P
WHERE
P.[object_id] = OBJECT_ID(N'dbo.Test', N'U')
AND P.index_id = 1
) + ')
WITH (INDEX(0));';
PRINT @SQL;
--EXECUTE (@SQL);
जो कि TABLESAMPLE
क्लॉज (यहां तक कि शून्य प्रतिशत) जो भी कहता है , हर पेज पर हर पंक्ति का चयन करेगा ।