একটি পুনরায় সূচি আপডেট পরিসংখ্যান না?


43

আমি গত সপ্তাহে এমএস 10775 এ কোর্সটি করছি এবং একটি প্রশ্ন এসেছিল যে প্রশিক্ষক নির্ভরযোগ্যভাবে উত্তর দিতে পারেন না:

একটি পুনরায় সূচী পরিসংখ্যান আপডেট করে?

আমরা এটি অনলাইনে আলোচনা করেছিলাম যে এটি করে এবং তা হয় না উভয়ই তর্ক করে।


এটি লক্ষণীয় যে দরকারী একটি REINDEXসূচক পুনর্নির্মাণের পার্শ্ব-প্রতিক্রিয়া হিসাবে কলামের পরিসংখ্যান আপডেট করে - আপনাকে পরিসংখ্যান আপডেট করার দরকার নেই । টেবিলের ডেটা পরিবর্তন হয় না। এটি একই ডেটা, এটি কেবল ক) স্পিনিং প্ল্যাটারে অবস্থানটি স্থানান্তরিত করেছে (যখন কোনও পৃষ্ঠা পুনর্গঠিত হয়), বা খ) ভিন্ন পৃষ্ঠায় বসে (পুনর্নির্মাণের ক্ষেত্রে)। তাই: একটি পুনরায় সূচক করে আপডেট (কিছু) পরিসংখ্যান: কোন আছে প্রয়োজন তা করতে।
ইয়ান বয়ড

উত্তর:


51

পরিসংখ্যান আপডেট করার বিষয়ে যত্ন নেওয়ার সময় আপনি নিম্নোক্ত বিষয়গুলি মাথায় রাখতে পারেন (পরিসংখ্যান পুনর্নির্মাণের বনাম। পরিসংখ্যান আপডেট করা (বেনিয়ামিন নেভারেজ)

  1. ডিফল্টরূপে, UPDATE STATISTICSবিবৃতিটি কেবল সারণীর রেকর্ডগুলির একটি নমুনা ব্যবহার করে। ব্যবহারের UPDATE STATISTICS WITH FULLSCANফলে পুরো টেবিলটি স্ক্যান হবে।

  2. ডিফল্টরূপে, UPDATE STATISTICSবিবৃতি সূচি এবং কলামের উভয় পরিসংখ্যান আপডেট করে। COLUMNSবিকল্পটি ব্যবহার করা কেবল কলামের পরিসংখ্যান আপডেট করবে। INDEXবিকল্পটি ব্যবহার করা কেবল সূচকের পরিসংখ্যানকে আপডেট করবে।

  3. একটি সূচক পুনর্নির্মাণ , উদাহরণস্বরূপ ব্যবহার করে টেবিল বিভক্ত না হওয়া অবধিALTER INDEX … REBUILD ব্যবহারের সমতুল্য সাথে সূচক পরিসংখ্যানও আপডেট করা হবে , সেক্ষেত্রে পরিসংখ্যান কেবল নমুনাযুক্ত হয় না (এসকিউএল সার্ভার 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;সিনট্যাক্সের সাহায্যে আপনি সূচী-পরিসংখ্যান এবং ম্যানুয়ালি তৈরি করা পরিসংখ্যান সহ কোনও টেবিলের সমস্ত পরিসংখ্যানের আপডেট আপডেট করতে পারেন ।

নিম্নলিখিত কোডটি উপরে encapsulated নিয়ম চিত্রিত:

প্রথমত, আমরা কয়েকটি কলাম এবং একটি ক্লাস্টার ইনডেক্স সহ একটি টেবিল তৈরি করব:

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';

ফলাফলগুলি দেখায় যে কোনও আপডেট এখনও হয়নি which যা সঠিকভাবে আমরা সারণীটি তৈরি করেছি:

╔═══════════════╦═══════════╦═══════════╗
Ject অবজেক্টনাম ║ স্ট্যাটাসনাম ║ স্ট্যাটাসডেট ║ ║
╠═══════════════╬═══════════╬═══════════╣
Bo dbo.SomeTable ║ cx ║ NULL ║
Bo dbo.SomeTable ║ i ║ NULL ║
Bo dbo.SomeTable ║ pk ║ NULL ║
Bo dbo.SomeTable ║ d ║ NULL ║
╚═══════════════╩═══════════╩═══════════╝

আসুন পুরো টেবিলটি পুনর্নির্মাণ করুন এবং দেখুন যে এটি পরিসংখ্যান আপডেট করে:

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';
╔═══════════════╦═══════════╦═════════════════════ ════╗
Ject অবজেক্টনাম ║ স্ট্যাটাসনাম ║ স্ট্যাটাসডেট ║ ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
Bo dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.590 ║
Bo dbo.SomeTable ║ i ║ NULL ║
Bo dbo.SomeTable ║ pk ║ NULL ║
Bo dbo.SomeTable ║ d ║ NULL ║
╚═══════════════╩═══════════╩═════════════════════ ════╝

ফলাফলগুলি দেখায় কেবল ক্লাস্টারড ইনডেক্সের পরিসংখ্যান আপডেট করা হয়েছিল।

এর পরে, আমরা একটি পৃথক 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কলামের পরিসংখ্যান সবেমাত্র আপডেট করেছি :

╔═══════════════╦═══════════╦═════════════════════ ════╗
Ject অবজেক্টনাম ║ স্ট্যাটাসনাম ║ স্ট্যাটাসডেট ║ ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
Bo dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.590 ║
Bo dbo.SomeTable ║ i ║ NULL ║
Bo dbo.SomeTable ║ pk ║ NULL ║
Bo dbo.SomeTable ║ d ║ 2018-09-17 14: 09: 13.597 ║
╚═══════════════╩═══════════╩═════════════════════ ════╝

এখন, আমরা সম্পূর্ণ টেবিলের পরিসংখ্যান আপডেট করব:

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';
╔═══════════════╦═══════════╦═════════════════════ ════╗
Ject অবজেক্টনাম ║ স্ট্যাটাসনাম ║ স্ট্যাটাসডেট ║ ║
╠═══════════════╬═══════════╬═════════════════════ ════╣
Bo dbo.SomeTable ║ cx ║ 2018-09-17 14: 09: 13.600 ║
Bo dbo.SomeTable ║ i ║ 2018-09-17 14: 09: 13.600 ║
Bo dbo.SomeTable ║ pk ║ 2018-09-17 14: 09: 13.603 ║
Bo dbo.SomeTable ║ d ║ 2018-09-17 14: 09: 13.607 ║
╚═══════════════╩═══════════╩═════════════════════ ════╝

যেমন আপনি দেখতে পাচ্ছেন, সমস্ত পরিসংখ্যান আপডেট হওয়ার একমাত্র উপায় হ'ল হয় ম্যানুয়ালি প্রতিটি আপডেট করা, বা সম্পূর্ণ টেবিলটি আপডেট করে UPDATE STATISTICS (table);


@ জেরেমিওয়ের - আপনি যেমন উপরে কোডটিতে সবে যুক্ত উদাহরণ কোড থেকে দেখতে পাচ্ছেন, কেবলমাত্র পরিসংখ্যানগুলি হ'ল হয় কোনও ALTER INDEX ... REBUILDবা UPDATE STATISTICSবিবৃতি দিয়ে স্পষ্টভাবে আপডেট করা হয়েছে। যদি টেবিলটি নিজেই পুনর্নির্মাণ করা হয় তবে কেবল ক্লাস্টারড ইনডেক্সের পরিসংখ্যান আপডেট করা হয়। এফওয়াইআই, একটি প্রাথমিক কী এবং একটি ক্লাস্টার্ড সূচক অগত্যা একই সূচী অবজেক্ট দ্বারা সমর্থিত নয়।
ম্যাক্স ভার্নন

5

এসকিউএল সার্ভারের পরিসংখ্যানগুলির জন্য মাইক্রোসফ্ট ডক্স পৃষ্ঠাটি বলে :

পুনর্নির্মাণ, ডিফ্র্যাগমেন্টিং বা সূচি পুনর্গঠনের মতো ক্রিয়াকলাপগুলি ডেটা বিতরণকে পরিবর্তন করে না। অতএব, অল্টার ইন্ডেক্স রিবেল্ড, ডিবিসিসি ডিবিআরআইএনডিএক্স, ডিবিসিসি ইন্ডেক্সডেফ্র্যাগ, অথবা আলেটার ইন্ডেক্স পুনরায় সংশোধন ক্রিয়াকলাপ সম্পাদনের পরে আপনার পরিসংখ্যান আপডেট করার দরকার নেই । আপনি যখন কোনও টেবিলে কোনও সূচকটি পুনর্নির্মাণ করেন বা ALTER INDEX REBUILD বা DBCC DBREINDEX এর সাথে দেখতে পান তখন কোয়েরি অপটিমাইজার পরিসংখ্যান আপডেট করে however তবে এই পরিসংখ্যান আপডেটটি সূচকটি পুনরায় তৈরির একটি উপজাত। ক্যোরি অপ্টিমাইজার ডিবিসিসি আইএনডিএক্সএক্সএক্সএডএক্সআরএফগ্র্যাগ বা অলটার ইন্ডেক্স পুঞ্জীকরণের ক্রিয়াকলাপের পরে পরিসংখ্যান আপডেট করে না।

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