পরিসংখ্যান আপডেটের জন্য নমুনা আকারের সাথে অদ্ভুত আচরণ


25

আমি এসকিউএল সার্ভার (২০১২) এর পরিসংখ্যান আপডেটের সাথে স্যাম্পলিং প্রান্তিকের তদন্তের চারপাশে খেলছি এবং কিছু কৌতূহলপূর্ণ আচরণ লক্ষ্য করেছি। মূলত নমুনাযুক্ত সারিগুলির সংখ্যা কিছু পরিস্থিতিতে পৃথক হতে পারে বলে মনে হয় - এমনকি একই ডেটা সেট করেও।

আমি এই ক্যোয়ারী চালাচ্ছি:

--Drop table if exists
IF (OBJECT_ID('dbo.Test')) IS NOT NULL DROP TABLE dbo.Test;

--Create Table for Testing
CREATE TABLE dbo.Test(Id INT IDENTITY(1,1) CONSTRAINT PK_Test PRIMARY KEY CLUSTERED, TextValue VARCHAR(20) NULL);

--Insert enough data so we have more than 8Mb (the threshold at which sampling kicks in)
INSERT INTO dbo.Test(TextValue) 
SELECT TOP 1000000 'blahblahblah'
FROM sys.objects a, sys.objects b, sys.objects c, sys.objects d;  

--Create Index on TextValue
CREATE INDEX IX_Test_TextValue ON dbo.Test(TextValue);

--Update Statistics without specifying how many rows to sample
UPDATE STATISTICS dbo.Test IX_Test_TextValue;

--View the Statistics
DBCC SHOW_STATISTICS('dbo.Test', IX_Test_TextValue) WITH STAT_HEADER;

আমি যখন শপ্পটিস্টিকসগুলির আউটপুট দেখি তখন আমি দেখতে পাচ্ছি যে "সারি নমুনা" প্রতিটি পূর্ণ প্রয়োগের সাথে পরিবর্তিত হয় (যেমন টেবিলটি বাদ পড়েছে, পুনরায় তৈরি করা হয়েছে এবং পুনরায় সাজানো হয়েছে)।

উদাহরণ স্বরূপ:

সারি নমুনা

  • 318618
  • 319240
  • 324198
  • 314154

আমার প্রত্যাশাটি ছিল যে টেবিলটি অভিন্ন হিসাবে এই চিত্রটি প্রতিবার একই হবে। যাইহোক, আমি যদি কেবল ডেটা মুছে ফেলি এবং পুনরায় সন্নিবেশ করি তবে আমি এই আচরণটি পাই না।

এটি কোনও সমালোচনামূলক প্রশ্ন নয়, তবে আমি কী চলছে তা বুঝতে আগ্রহী।


2
আপনি যে ফাইলগ্রুপে serোকাচ্ছেন তাতে কতগুলি ফাইল রয়েছে? আমি 2016 বার দুয়েক চেষ্টা করেছি এবং উভয় বার টেবিল 279 সারি দিয়ে 3584 পৃষ্ঠাগুলি এবং 1 64. সঙ্গে দুটি ভিন্ন নমুনা মাপ আমি দেখেছি 314712 এবং 315270 ছিল বিভক্ত ছিল - এর 279. উভয় সঠিক গুণিতক
মার্টিন স্মিথ

1
@ জোওববিশ - এটি সর্বদা পুরো পৃষ্ঠাগুলি এএফআইকে পড়ে তাই আমি এতে অবাক হইনি। কিছু কারণে আমি ভেবেছিলাম যে প্রশ্নের নম্বরগুলি সেই ধরণের সাথে মেলে না। তবে তারা করা গণিতগুলি আবার করেছে one 318618 = 1142*279, 319240 = 1144*279 + 64, 324198=1162*279এবং 314154=1126তাই ভ্যারিয়েন্স নমুনা পৃষ্ঠাগুলির সংখ্যা।
মার্টিন স্মিথ

@ মার্টিনস্মিথ কেবল একটি ফাইল - 279 চিত্রটি আকর্ষণীয়, আমি সবসময় জড়িত নিদর্শনগুলি বুঝতে পছন্দ করি
ম্যাথু ম্যাকগিফেন

উত্তর:


26

পটভূমি

ফর্মের একটি বিবৃতি ব্যবহার করে পরিসংখ্যান অবজেক্টের ডেটা সংগ্রহ করা হয়:

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) এর সাহায্যে এই বিবৃতিটি সংগ্রহ করতে পারেন ।

পরিসংখ্যান তৈরির প্রশ্নগুলি প্রায়শই নন ক্ল্লাস্টারড সূচক পৃষ্ঠাগুলিতে প্রাকৃতিকভাবে ঘটে এমন মানগুলির ক্লাস্টারিং এড়ানোর জন্য বেস টেবিলটি (একটি নন ক্ল্লাস্টারড ইনডেক্সের পরিবর্তে) অ্যাক্সেস করে।

নমুনাযুক্ত সারিগুলির সংখ্যা নমুনার জন্য নির্বাচিত পুরো পৃষ্ঠাগুলির সংখ্যার উপর নির্ভর করে। সারণীর প্রতিটি পৃষ্ঠা হয় নির্বাচিত বা এটি নয়। নির্বাচিত পৃষ্ঠাগুলির সমস্ত সারি পরিসংখ্যানগুলিতে অবদান রাখে।

এলোমেলো সংখ্যা

এসকিউএল সার্ভার কোনও পৃষ্ঠা যোগ্যতা অর্জন করে কিনা তা নির্ধারণ করতে এলোমেলো সংখ্যা জেনারেটর ব্যবহার করে। এই উদাহরণে ব্যবহৃত জেনারেটরটি প্যারামিটার মানগুলির সাথে নীচে প্রদর্শিত হিসাবে লেহমার র্যান্ডম নম্বর জেনারেটর :

এক্স পরবর্তী = এক্স বীজ * 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" />

এসকিউএল সার্ভার ২০১২-এর জন্য, এই গণনাটি এখানে ঘটে 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';

এজ কেস

এমআইএনএসটিডি লেহমার এলোমেলো সংখ্যা জেনারেটর ব্যবহারের একটি ফল হ'ল বীজের মান শূন্য এবং ইনটম্যাক্স ব্যবহার করা উচিত নয় কারণ এর ফলে অ্যালগরিদম শূন্যের ক্রম তৈরি করবে (প্রতিটি পৃষ্ঠা নির্বাচন করে)।

কোডটি শূন্য সনাক্ত করে এবং সিস্টেম 'ঘড়ি' থেকে সেই ক্ষেত্রে বীজ হিসাবে একটি মান ব্যবহার করে। বীজটি int.max হলে এটি একই রকম হয় না ( 0x7FFFFFFF= 2 31 - 1)।

পার্টিশন আইডির কম 32 বিটের যোগফল হিসাবে প্রাথমিক বীজ গণনা করা হওয়ায় আমরা এই দৃশ্যটি ইঞ্জিনিয়ার করতে পারি REPEATABLEREPEATABLEমান 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ক্লাজ যা বলুক না কেন প্রতিটি পৃষ্ঠায় প্রতিটি সারি নির্বাচন করবে (এমনকি শূন্য শতাংশ)।


11

এটি একটি চমৎকার প্রশ্ন! আমি নিশ্চিতভাবে যা জানি তা দিয়ে শুরু করব এবং তারপরে অনুমানের দিকে এগিয়ে চলেছি। আমার ব্লগ পোস্টে এ সম্পর্কে প্রচুর বিশদ এখানে

নমুনা সংক্রান্ত পরিসংখ্যান আপডেটগুলি TABLESAMPLEপর্দার আড়ালে ব্যবহার করে। অনলাইন সম্পর্কে ডকুমেন্টেশন সন্ধান করা বেশ সহজ। তবে, আমি বিশ্বাস করি যে এটি সুনির্দিষ্টভাবে জানা যায় না যে সারিগুলি TABLESAMPLEআংশিকভাবে ফিরে এসেছে hobt_idএটি বস্তুর উপর নির্ভর করে । আপনি যখন বস্তুটি ড্রপ এবং পুনরায় তৈরি করবেন তখন আপনি একটি নতুন পাবেন hobt_idযাতে এলোমেলো নমুনা দ্বারা ফিরে আসা সারিগুলি আলাদা।

আপনি যদি ডেটা মুছলে এবং পুনরায় প্রবেশ করান hobt_idতবে একই থাকে s যতক্ষণ না ডিস্কের উপর ডেটা একইভাবে বিছানো হয় (একটি বরাদ্দ আদেশ স্ক্যান একই ক্রমে একই ফলাফল ফেরত দেয়) তারপরে নমুনাযুক্ত ডেটা পরিবর্তন করা উচিত নয়।

আপনি টেবিলের ক্লাস্টারড ইনডেক্স পুনর্নির্মাণের মাধ্যমে নমুনাযুক্ত সারিগুলির সংখ্যাও পরিবর্তন করতে পারেন। উদাহরণ স্বরূপ:

UPDATE STATISTICS dbo.Test IX_Test_TextValue;

DBCC SHOW_STATISTICS('dbo.Test', IX_Test_TextValue) WITH STAT_HEADER; -- 273862 rows

ALTER INDEX PK_Test on Test REBUILD;

UPDATE STATISTICS dbo.Test IX_Test_TextValue;

DBCC SHOW_STATISTICS('dbo.Test', IX_Test_TextValue) WITH STAT_HEADER; -- 273320 rows

কেন এটি হয় তা হিসাবে, আমি বিশ্বাস করি এটি কারণ এসকিউএল সার্ভার একটি সূচীতে নমুনাযুক্ত পরিসংখ্যান সংগ্রহ করার সময় ননক্র্লাস্টারড সূচির পরিবর্তে ক্লাস্টারড ইনডেক্স স্ক্যান করে। আমিও মনে করি যে একটা (আমাদের মধ্যে যারা গোপন পরিসংখ্যান আপডেট প্রশ্নের ট্রেসিং করার জন্য) গোপন মান REPEATABLEসঙ্গে ব্যবহার TABLESAMPLE। আমি এর কোনও প্রমাণ পাইনি, তবে এটি ব্যাখ্যা করে যে কেন আপনার হিস্টোগ্রাম এবং সারিগুলি ক্লাস্টারড সূচক পুনর্নির্মাণের সাথে নমুনা পরিবর্তন করেছিল।


3

আমি ভুলে গিয়েছিলাম যে টেবিলসাম্পল কীভাবে প্রতি পৃষ্ঠায় একটি এলোমেলো সম্ভাবনা নির্ধারণের ক্ষেত্রে কাজ করেছিল। - মার্টিন স্মিথ

আমি এটি মাইক্রোসফ্ট এসকিউএল সার্ভার ২০০৮-এ দেখেছি : ইটজিক বেন-গানের টি-এসকিউএল কোয়েরি করা এবং আমি এটি একটি মন্তব্য হিসাবে যুক্ত করতে পারি না তাই আমি এটি এখানে পোস্ট করি, আমি মনে করি এটি অন্যদের কাছেও আকর্ষণীয়:

এখানে চিত্র বর্ণনা লিখুন

রোজি কর্তৃক সারণী স্যাম্পল ব্যবহার করে নমুনা দেখুন । পি টমাস

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.