সরল অল্টার টেবল কমান্ড পুরো-পাঠ্য সূচী সহ টেবিলে এত দীর্ঘ সময় নেয় কেন?


14

আমার কাছে একটি বড় (~ 67 মিলিয়ন সারি) নাম-মান সারণী রয়েছে যাতে DataValueকলামটিতে পূর্ণ-পাঠ্য সূচী রয়েছে ।

যদি আমি নিম্নলিখিত কমান্ডটি চালানোর চেষ্টা করি:

ALTER TABLE VisitorData ADD NumericValue bit DEFAULT 0 NOT NULL;

এটি 1 ঘন্টা 10 মিনিটের জন্য চলে এবং এখনও VisitorDatatable 67 মিলিয়ন সারি রয়েছে এমন কোনও টেবিলে পূর্ণ হয় না not

  1. কেন এটি এত দিন নিচ্ছে এবং শেষ হচ্ছে না?
  2. আমি এটি সম্পর্কে কি করতে পারি?

এখানে টেবিল সম্পর্কে আরও বিশদ রয়েছে:

CREATE TABLE [dbo].[VisitorData](
            [VisitorID] [int] NOT NULL,
            [DataName] [varchar](80) NOT NULL,
            [DataValue] [nvarchar](3800) NOT NULL,
            [EncryptedDataValue] [varbinary](max) NULL,
            [VisitorDataID] [int] IDENTITY(1,1) NOT NULL, 
CONSTRAINT [PK_VisitorData_VisitorDataID] PRIMARY KEY CLUSTERED (
            [VisitorDataID] ASC
) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY], 
CONSTRAINT [UNQ_VisitorData_VisitorId_DataName] UNIQUE NONCLUSTERED (
            [VisitorID] ASC,
            [DataName] ASC
) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
        ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[VisitorData]
ADD  CONSTRAINT [UNQ_VisitorData_VisitorDataID] UNIQUE NONCLUSTERED (

[VisitorDataID] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,
      IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, 
      ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

ALTER TABLE [dbo].[VisitorData]
    WITH CHECK ADD
        CONSTRAINT [FK_VisitorData_Visitors] FOREIGN KEY([VisitorID])
        REFERENCES [dbo].[Visitors] ([VisitorID])
GO

ALTER TABLE [dbo].[VisitorData]
    CHECK CONSTRAINT [FK_VisitorData_Visitors] GO

CREATE FULLTEXT CATALOG DBName_VisitorData_Catalog WITH ACCENT_SENSITIVITY = ON
CREATE FULLTEXT INDEX ON VisitorData ( DataValue Language 1033 )
    KEY INDEX UNQ_VisitorData_VisitorDataID
    ON DBName_VisitorData_Catalog
    WITH CHANGE_TRACKING AUTO
GO

ALTER TABLEকমান্ড চলাকালীন অপেক্ষা করার LCK_M_SCH_Mধরণগুলি হ'ল (স্কিমা পরিবর্তন), নীচের প্রশ্নের ফলাফল অনুসারে:

select * from  sys.dm_os_waiting_tasks

waiting_task_address    session_id exec_context_id wait_duration_ms     wait_type            resource_address       blocking_task_address   blocking_session_id blocking_exec_context_id resource_description
--------------------             ----------     --------------- --------------------              -------------------- ------------------             ---------------------            -------------------        ------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0x0000000000B885C8   54               0                   112695                            LCK_M_SCH_M   0x00000000802DF600 0x000000000054E478     25                            0                                         objectlock lockPartition=0 objid=834102012 subresource=FULL dbid=5 id=lock438a02e80 mode=IS associatedObjectId=834102012
0x0000000000B885C8   54               0                   112695                            LCK_M_SCH_M   0x00000000802DF600 0x00000000088AB048    23                            0                                         objectlock lockPartition=0 objid=834102012 subresource=FULL dbid=5 id=lock438a02e80 mode=IS associatedObjectId=834102012

আমি প্রোডাকশন সার্ভারগুলির সাথে কাজ করছি যা এসকিউএল সার্ভার 2005 এসপি 2 চালাচ্ছে (শীঘ্রই ২০০৮ এসপি 2 এ উন্নীত করা হবে)।

উত্তর:


16

স্কিমাটি এটিকে এত দীর্ঘ সময় নিয়েছে কারণ আপনি পরিবর্তনের সময় কলামটিতে একটি ডিফল্ট মান নির্ধারণ করছেন এবং একটি অ-অযোগ্য কলাম সহ এটি প্রয়োগ করছেন এবং এটি 60+ মিলিয়ন সারিগুলির জন্য কলামটি পপুলেট করতে হবে, এটি একটি অবিশ্বাস্য ব্যয়বহুল ক্রিয়াকলাপ। আমি নিশ্চিত নই যে আপনার আবেদনের প্রয়োজনীয়তাগুলি কী তবে এটি এমন একটি পদ্ধতির যা স্কিমাটি দ্রুত পরিবর্তন করবে তা হ'ল এটিকে কোনও ডিফল্ট মান ছাড়াই একটি নল কলাম হিসাবে যুক্ত করা এবং তারপরে কলামের মান হিসাবে 0 নির্ধারণের জন্য ব্যাচগুলিতে একটি আপডেট সম্পাদন করা। আপনার আপডেটটি শেষ হয়ে যাওয়ার পরে আপনি কলামটি নন-অ্যালবামে পরিবর্তন করতে এবং ডিফল্ট মান নির্ধারণ করতে অন্য স্কিমা পরিবর্তন প্রয়োগ করতে পারেন।


9

সম্পূর্ণ-পাঠ্য-সূচীকরণ সম্ভবত আপনার সমস্যার অপ্রাসঙ্গিক। এসকিউএল সার্ভার ২০১২-এর পূর্ববর্তীটি ADD COLUMN NOT NULL DEFAULT ...একটি অফলাইন ক্রিয়াকলাপ যা একটি আপডেট চালাতে হবে এবং সদ্য যুক্ত হওয়া কলামটির নতুন ডিফল্ট মান সহ প্রতিটি সারিকে পপুলেট করতে হবে। এসকিউএল সার্ভার ২০১২-এ, অপারেশনটি আরও দ্রুত, এসকিউএল সার্ভার ১১-এ মান কলাম যুক্ত অনলাইনে অ-নুল দেখুন, কারণ এটি কেবলমাত্র সারণির মেটাডেটা আপডেট করে এবং কোনও সারি আপডেট করে না।

তোমার ALTER TABLEসম্ভবত আপডেটের কারণে ধীর। মনে রাখবেন যেহেতু এটি একটি একক লেনদেন, তাই একটি বিশাল লগ তৈরি হবে এবং আপনার লগটি সম্ভবত এখন বৃদ্ধি পাচ্ছে এবং প্রসারিত হওয়ার সাথে সাথে ক্রমাগত শূন্য-সম্পাদনা করা হচ্ছে। তবে, সাধারণ বিতর্ক কারণে এটি ধীর হতে পারে: বিবৃতিটি টেবিলের এসএইচ-এম লকটি অর্জন করতে সক্ষম হতে পারে না। এ sys.dm_exec_requestsঘটনাটি কিনা তা দেখানো উচিত wait_typeএবং wait_resourceবিবরণটিকে ALTERঅবরুদ্ধ করা হয়েছে বা অগ্রগতি হচ্ছে কিনা তা এবং কলামগুলি সূচিত করবে ।


0

উত্তরটির মূলত এর লেখকের প্রশ্নের সাথে যুক্ত হয়েছে:

অনুযায়ী জেসনের উত্তর , আমি নিম্নলিখিত আপডেট পরিবর্তে ইস্যু করেছে:

ALTER TABLE VisitorData ADD NumericValue bit NULL

এটি শেষ পর্যন্ত কার্যকর করেছে, তবে 29 মিনিট, 16 সেকেন্ড সময় নিয়েছিল। অপারেশনটি নিজেই বেশ দ্রুত হওয়া উচিত (কেবলমাত্র মেটাডেটা) কেবলমাত্র আমি কল্পনা করেছিলাম যে প্রায় সময়টি প্রায় প্রয়োজনীয় LCK_M_SCH_M(স্কিমা পরিবর্তন) লকটি অর্জনের জন্য অপেক্ষা করতে ব্যয় করেছিল ।

নতুন bitক্ষেত্রের জায়গায়, আমি স্ক্রিপ্টের মাধ্যমে এটিতে ডিফল্ট মানটি দ্রুত যুক্ত করতে সক্ষম হয়েছি:

ALTER TABLE VisitorData ADD
CONSTRAINT DF_VisitorData_NumericValue DEFAULT(0) FOR NumericValue;

আমি এখন NumericValueব্যবহারকারী-সংজ্ঞায়িত ফাংশনটি ব্যবহার করে টেবিলের সমস্ত বিট সেট করার প্রক্রিয়াধীন (নীচে দেখুন)। এটি অগ্রগতিতে এবং 1 68 মিলিয়ন ডলার সারি সারণীতে প্রতি 1 মিলিয়ন সারিতে প্রায় 1 মিনিট সময় নেয়।

WITH RD_CTE (VisitorD, DataName) 
AS
(
    SELECT TOP 10000 VisitorD, DataName
    FROM VisitorData WITH (NOLOCK)
    WHERE NumericValue IS NULL  
)
UPDATE VisitorData
SET NumericValue = CASE WHEN dbo.ufn_IsReallyNumeric(rd.DataValue) = 1 THEN 1 ELSE 0 END
FROM VisitorData rd WITH (NOLOCK) 
INNER JOIN RD_CTE rdc WITH (NOLOCK) ON rd.VisitorD = rdc.VisitorD  AND rd.DataName = rdc.DataName

GO 6800

এটি সম্পূর্ণ হয়ে গেলে, আমি এই নতুন বিট কলামটি শূন্য করার জন্য চূড়ান্ত স্কিমা সমন্বয় চালানোর পরিকল্পনা করছি:

ALTER TABLE VisitorData ALTER COLUMN NumericValue bit NOT NULL;

আশা করা যায়, একবারে সমস্ত মান অকার্যকর হয়ে গেলে এবং NumericValueপূর্বনির্ধারিত স্থানে থাকলে এই শেষ স্কিমা আপডেটটি দ্রুত চলে যাবে run

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