যখন পরিসংখ্যানের অটো_আপডেট হয় তখন একটি শ্বেতপত্র রয়েছে । পরিসংখ্যানগুলিতে স্বয়ংক্রিয় আপডেটগুলি দেখার জন্য এখানে মূল পয়েন্টগুলি রয়েছে:
- সারণির আকার 0 থেকে> 0 টি সারি (পরীক্ষা 1) এ চলে গেছে।
- পরিসংখ্যান সংগ্রহ করার সময় সারণীতে সারিগুলির সংখ্যা 500 বা তারও কম ছিল এবং পরিসংখ্যান অবজেক্টের শীর্ষস্থানীয় কলামের কলমডাক্টর তখন থেকে 500 টিরও বেশি পরিবর্তিত হয়েছিলেন (পরীক্ষা 2)।
- পরিসংখ্যান সংগ্রহ করার সময় সারণিতে 500 টিরও বেশি সারি ছিল, এবং পরিসংখ্যানের অবজেক্টের শীর্ষস্থানীয় কলামের কলমডাক্টর টেবিলে সারি সংখ্যার 500 + 20% এর বেশি পরিবর্তিত হয়েছিলেন (পরিসংখ্যান 3) ।
সুতরাং @ জেএনকে একটি মন্তব্যে এই বিষয়টি উল্লেখ করেছে যে আপনার যদি কোনও টেবিলে ১ বিলিয়ন সারি থাকে, তবে আপডেটটি ট্রিগার করার জন্য আপনার কাছে পরিসংখ্যানের প্রথম কলামে ২০,০০,৫০০০ লেখার দরকার আছে।
আসুন নিম্নলিখিত কাঠামো গ্রহণ করা যাক:
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')
যাইহোক, এটি একটি অর্থবহ পরিসংখ্যানগত বস্তু কিনা তা দেখতে আমাদের দরকার:
dbcc show_statistics('dbo.test_table',cix_test_table)
সুতরাং এই পরিসংখ্যান আপডেট করা হয়নি। এর কারণ এটি দেখে মনে হচ্ছে পরিসংখ্যানগুলি কোনও আপডেট না হওয়া অবধি আপডেট হয় না SELECT
এবং তারপরেও SELECT
এসিকিউএল সার্ভারের হিস্টোগ্রামের মধ্যে যা আছে তার বাইরে পড়তে হয়। এখানে একটি পরীক্ষা স্ক্রিপ্ট যা আমি এটি পরীক্ষা করতে দৌড়েছি:
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
যাতে আপনি সেই মানগুলি সম্পর্কে আরও ভাল অনুমানের জন্য একটি অতিরিক্ত পদক্ষেপ দিতে পারেন।
একবার আপনার এই ফিল্টার করা পরিসংখ্যানগুলি স্থানে রাখলে আপনি নিজেই পরিসংখ্যান আপডেট করার সম্ভাবনাটি দেখতে পারেন।