নট নল থেকে নূলে একটি কলাম পরিবর্তন করা - হুডের নীচে কী চলছে?


25

আমাদের এতে ২.৩ বি সারি সহ একটি টেবিল রয়েছে। আমরা একটি কলামটি নল নাল থেকে নূলে পরিবর্তন করতে চাই। কলামটি একটি সূচীতে রয়েছে (গুচ্ছ বা পিকে সূচক নয়)। ডেটা টাইপ পরিবর্তন হচ্ছে না (এটি একটি আইএনটি)। স্রেফ শূন্যতা। বিবৃতিটি নিম্নরূপ:

Alter Table dbo.Workflow Alter Column LineId Int NULL

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

প্রশ্নের মধ্যে থাকা সারণীটি গুচ্ছযুক্ত (একটি গাদা নয়)।


2
আমি মনে করি এটি সমস্ত পাতার স্তরের ডেটাপেজে নাল বিটম্যাপটি আপডেট করতে হবে। এবং ২.৩ বি সারি দিয়ে আমি বাজি ধরেছি যে এতে প্রচুর পৃষ্ঠা কাজ করতে পারে। যদিও আমি এই সম্পর্কে খুব নিশ্চিত নই।
স্যুপ্লেক্স

3
সূচকেও নাল বিটম্যাপ স্থাপনে ব্যস্ত হতে পারে। সূচী সংজ্ঞাটির সমস্ত কলাম অংশ নাল নয় বলে সংজ্ঞায়িত করা হলে নন বিএসটিএমএল নন-ক্লাস্টার্ড ইনডেক্সে উপস্থিত হবে না।
স্যুপ্লেক্স

উত্তর:


27

মন্তব্যে @ সপলেক্সের দ্বারা ইঙ্গিত হিসাবে একটি সম্ভাব্য ব্যাখ্যা হতে পারে যদি এই কলামটি NULLনন-ক্লাস্টারড ইনডেক্সে অংশগ্রহন করে এমন প্রথম- যোগ্য কলাম হয়।

নিম্নলিখিত সেটআপ জন্য

CREATE TABLE Foo
  (
     A UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY,
     B CHAR(1) NOT NULL DEFAULT 'B'
  )

CREATE NONCLUSTERED INDEX ix
  ON Foo(B);

INSERT INTO Foo
            (B)
SELECT TOP 100000 'B'
FROM   master..spt_values v1,
       master..spt_values v2 

sys.dm_db_index_physical_stats দেখায় যে নন ক্লাস্টারযুক্ত সূচীতে ix248 টি পাতা পৃষ্ঠা এবং একটি একক মূল পৃষ্ঠা রয়েছে।

একটি সূচক পাতার পৃষ্ঠাতে একটি সাধারণ সারি মনে হয়

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

এবং মূল পৃষ্ঠায়

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

তারপরে চলছে ...

CHECKPOINT;

GO

ALTER TABLE Foo ALTER COLUMN B  CHAR(1) NULL;


SELECT Operation, 
       Context,
       ROUND(SUM([Log Record Length]) / 1024.0,1) AS [Log KB],
       COUNT(*) as [OperationCount]
FROM sys.fn_dblog(NULL,NULL)
WHERE AllocUnitName = 'dbo.Foo.ix'
GROUP BY Operation, Context

ফেরৎ

+-----------------+--------------------+-------------+----------------+
|    Operation    |      Context       |   Log KB    | OperationCount |
+-----------------+--------------------+-------------+----------------+
| LOP_SET_BITS    | LCX_GAM            | 4.200000    |             69 |
| LOP_FORMAT_PAGE | LCX_IAM            | 0.100000    |              1 |
| LOP_SET_BITS    | LCX_IAM            | 4.200000    |             69 |
| LOP_FORMAT_PAGE | LCX_INDEX_INTERIOR | 8.700000    |              3 |
| LOP_FORMAT_PAGE | LCX_INDEX_LEAF     | 2296.200000 |            285 |
| LOP_MODIFY_ROW  | LCX_PFS            | 16.300000   |            189 |
+-----------------+--------------------+-------------+----------------+

সূচকের পাতাগুলি আবার চেক করা সারিগুলিকে এখন দেখতে দেখতে ভাল লাগে

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

এবং নীচের মতো উপরের স্তরের পৃষ্ঠাগুলিতে সারিগুলি।

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

প্রতিটি সারি আপডেট করা হয়েছে এবং এখন কলাম গণনার জন্য দুটি বাইট পাশাপাশি NULL_BITMAP এর জন্য অন্য বাইট রয়েছে।

অতিরিক্ত সারি প্রস্থের কারণে নন ক্লাস্টারড ইনডেক্সের এখন 285 পাতার পৃষ্ঠা এবং এখন মূল পৃষ্ঠার পাশাপাশি দুটি মধ্যবর্তী স্তরের পৃষ্ঠা রয়েছে।

কার্যকর করার পরিকল্পনা

 ALTER TABLE Foo ALTER COLUMN B  CHAR(1) NULL;

নিম্নলিখিত হিসাবে দেখায়

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

এটি বিদ্যমান সূচি আপডেট করার পরিবর্তে পৃষ্ঠাগুলি বিভক্ত করার পরিবর্তে সূচকের একদম নতুন অনুলিপি তৈরি করে।


9

এটি অবশ্যই ক্লাস্টারবিহীন সূচি পুনরায় তৈরি করবে এবং কেবলমাত্র মেটাডেটা আপডেট করবে না। এটি এসকিউএল ২০১৪ এ পরীক্ষা করা হয় এবং কোনও প্রোডাকশন সিস্টেমে সত্যই পরীক্ষা করা উচিত নয়:

CREATE TABLE [z](
    [a] [int] IDENTITY(1,1) NOT NULL,
    [b] [int] NOT NULL,
 CONSTRAINT [c_a] PRIMARY KEY CLUSTERED  ([a] ASC))
go
CREATE NONCLUSTERED INDEX [nc_b] on z (b asc)
GO
insert into z (b)
values (1);

এবং এখন মজাদার অংশের জন্য:

DBCC IND (0, z, -1)

এটি আমাদের ডাটাবেস পৃষ্ঠাগুলি দেবে যেখানে সারণী এবং নন ক্লাস্টারড সূচকটি সঞ্চিত আছে।

এই PagePIDযেখানে IndexID2 এবং PageType2, এবং তারপর নিচের কাজগুলো করুন:

DBCC TRACEON(3604) --are you sure that you are allowed to do this?

এবং তারপর:

dbcc page (0, 1, PagePID, 3) with tableresults

লক্ষ্য করুন যে শিরোনামটিতে নাল বিটম্যাপ রয়েছে:

পৃষ্ঠা শিরোনামের নির্যাস

এখন করা যাক:

alter table z alter Column b int null;

আপনি যদি সত্যিই অধৈর্য হন তবে আপনি dbcc pageকমান্ডটি আবার চালানোর চেষ্টা করতে পারেন তবে এটি ব্যর্থ হবে, সুতরাং আসুনটি আবার পরীক্ষা করে দেখুন DBCC IND (0, z, -1)। পৃষ্ঠাটি ম্যাজিকের মতো সরে গেছে।

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


এসকিউএল সার্ভার 2016 দিয়ে শুরু করে অনেকগুলি ALTER TABLE ... ALTER COLUMN ...অপারেশন করা যেতে পারে ONLINEতবে:

ALTER TABLE (Transact-SQL)

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