স্পারস তৈরি টেবিলটি আরও বড় করা


9

আমার জেনেরিক লগ টেবিল রয়েছে, প্রায় 5 মিটার সারি।
একটি "দৃ stores়ভাবে টাইপড" ক্ষেত্র রয়েছে যা ইভেন্টের ধরণ সঞ্চয় করে এবং "হারানো টাইপড" কলামগুলির একটি গোছা থাকে যা ইভেন্টের সাথে সম্পর্কিত ডেটা ধারণ করে। এটি হল, সেই "হারানো টাইপ করা" কলামগুলির অর্থ ইভেন্টের ধরণের উপর নির্ভর করে।

এই কলামগুলি হিসাবে সংজ্ঞায়িত করা হয়েছে:

USER_CHAR1 nvarchar(150) null,
USER_CHAR2 nvarchar(150) null,
USER_CHAR3 nvarchar(150) null,
USER_CHAR4 nvarchar(150) null,
USER_CHAR5 nvarchar(150) null,

USER_INTEGER1 int null,
USER_INTEGER2 int null,
USER_INTEGER3 int null,
USER_INTEGER4 int null,
USER_INTEGER5 int null,

USER_FLAG1 bit null,
USER_FLAG2 bit null,
USER_FLAG3 bit null,
USER_FLAG4 bit null,
USER_FLAG5 bit null,

USER_FLOAT1 float null,
USER_FLOAT2 float null,
USER_FLOAT3 float null,
USER_FLOAT4 float null,
USER_FLOAT5 float null

প্রতিটি ধরণের 1 এবং 2 কলামগুলি প্রচুর পরিমাণে ব্যবহৃত হয়, তবে 3 নম্বর থেকে শুরু হয়ে খুব কম ইভেন্টের ধরণের এই তথ্য সরবরাহ করে। তাই আমি প্রতিটি প্রকারে 3-5 কলাম চিহ্নিত করতে চেয়েছি SPARSE

আমি প্রথমে কিছু বিশ্লেষণ করেছি, এবং দেখেছি যে, প্রকৃতপক্ষে, এই কলামগুলির প্রত্যেকটিতে কমপক্ষে 80% ডেটা রয়েছে nullএবং প্রায় 100% ডেটা হয় null। মতে 40% সেভিংস থ্রেশহোল্ড টেবিল , SPARSEতাদের উপর একটি বিশাল জয় হবে।

তাই আমি গিয়ে SPARSEপ্রতিটি গ্রুপে 3-5 কলামে প্রয়োগ করেছি applied এখন রিপোর্ট করা হিসাবে আমার টেবিলটি ডেটা স্পেসে প্রায় 1.8 গিগাবাইট নেয় sp_spaceused, অন্যদিকে স্পার্স করার আগে এটি 1 জিবি ছিল।

আমি চেষ্টা করেছিলাম dbcc cleantable, কিন্তু এর কোনও প্রভাব ছিল না।
তারপরে dbcc shrinkdatabase, কোনও প্রভাব নেই।

বিস্মিত, আমি অপসারণ SPARSEএবং এর পুনরাবৃত্তি dbcc। টেবিলের আকারটি 1.8 গিগাবাইটে থেকে যায়।

কি দেয়?


চেষ্টা এবং পুনরুত্পাদন হবে। কেবলমাত্র যদি এটি কোনও পার্থক্য করে তবে টেবিলটি হিপ বা এটির একটি ক্লাস্টার ইনডেক্স রয়েছে?
মার্টিন স্মিথ 16

@ মার্টিনস্মিথের একটি ক্লাস্টার্ড সূচক রয়েছে rowid int not null identity(1,1) primary key clustered
GSerg

উত্তর:


14

কলামগুলিকে বিচ্ছিন্ন করার পরে আপনাকে ক্লাস্টারড ইনডেক্স পুনর্নির্মাণ করতে হবে। বাদ দেওয়া কলামগুলি তথ্যের পৃষ্ঠায় এখনও অবধি রয়েছে যতক্ষণ না আপনি এটি না করেন ততক্ষণ আপনি sys.system_internals_partition_columnsব্যবহারের বিরুদ্ধে বা ব্যবহারের সাথে কোনও কোয়েরির সাথে দেখা যায় নাDBCC PAGE

SET NOCOUNT ON;
CREATE TABLE Thing 
(
ThingId int IDENTITY CONSTRAINT PK PRIMARY KEY,
USER_CHAR1 nvarchar(150) null,
USER_CHAR2 nvarchar(150) null,
USER_CHAR3 nvarchar(150) null,
USER_CHAR4 nvarchar(150) null,
USER_CHAR5 nvarchar(150) null
)
INSERT INTO Thing
SELECT REPLICATE('A',150),
       CASE WHEN number % 5 = 1 THEN REPLICATE('A',150) END,
       CASE WHEN number % 5 = 2 THEN REPLICATE('A',150) END,
       CASE WHEN number % 5 = 3 THEN REPLICATE('A',150) END,              
       CASE WHEN number % 5 = 4 THEN REPLICATE('A',150) END
FROM master..spt_values   

EXEC sp_spaceused 'Thing'

ALTER TABLE dbo.Thing ALTER COLUMN USER_CHAR2 ADD SPARSE
ALTER TABLE dbo.Thing ALTER COLUMN USER_CHAR3 ADD SPARSE
ALTER TABLE dbo.Thing ALTER COLUMN USER_CHAR4 ADD SPARSE
ALTER TABLE dbo.Thing ALTER COLUMN USER_CHAR5 ADD SPARSE

DECLARE @DynSQL NVARCHAR(MAX);

SELECT @DynSQL =  'DBCC TRACEON (3604);
                   DBCC PAGE(0, ' + LEFT(file_id,10) + ', ' + LEFT(page_id,10) + ', 3); 
                   DBCC TRACEOFF(3604); ' 
FROM Thing
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%)
WHERE ThingId=76

EXEC(@DynSQL)    

SELECT pc.*
FROM sys.system_internals_partition_columns pc
JOIN sys.partitions p on p.partition_id=pc.partition_id
WHERE p.object_id = object_id('Thing')
AND pc.is_dropped=1

 EXEC sp_spaceused 'Thing'

ALTER INDEX PK ON Thing REBUILD;    

SELECT @DynSQL =  'DBCC TRACEON (3604);
                   DBCC PAGE(0, ' + LEFT(file_id,10) + ', ' + LEFT(page_id,10) + ', 3); 
                   DBCC TRACEOFF(3604); ' 
FROM Thing
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%)
WHERE ThingId=76

EXEC(@DynSQL)    

SELECT pc.*
FROM sys.system_internals_partition_columns pc
JOIN sys.partitions p on p.partition_id=pc.partition_id
WHERE p.object_id = object_id('Thing')
AND pc.is_dropped=1

EXEC sp_spaceused 'Thing'

DROP TABLE Thing 

1
অসাধারণ. আমাদের কি এটি ডকুমেন্টেশনের বাগ হিসাবে নেওয়া উচিত ? "এসকিউএল সার্ভার ডেটাবেস ইঞ্জিন এই পরিবর্তনটি সম্পাদন করতে নিম্নলিখিত পদ্ধতিটি ব্যবহার করে: 1) নতুন স্টোরেজের আকার এবং ফর্ম্যাটে টেবিলটিতে একটি নতুন কলাম যুক্ত করে)) সারণীতে প্রতিটি সারিটির জন্য, পুরানোতে সঞ্চিত মান আপডেট করে এবং অনুলিপি করে নতুন কলামে কলাম। 3) টেবিল স্কিমা থেকে পুরানো কলামটি সরিয়ে দেয় 4) পুরাতন কলাম দ্বারা ব্যবহৃত স্থান পুনরায় দাবি করতে টেবিলটি পুনর্নির্মাণ করে ""
জিএসবার্গ

3
@ জিসার্গ - ঠিক আছে। সম্মত মনে হচ্ছে পয়েন্ট 4 সঠিক নয়। প্রদত্ত যে আপনি 12 টি কলামের জন্য এটি করছেন তবে আপনি চাইবেন না যে প্রতিটি কলামের জন্য পুনর্নির্মাণটি স্পষ্টভাবে ঘটুক যদিও মনে হয় আচরণটি সঠিক তবে ডকুমেন্টেশন নয়।
মার্টিন স্মিথ

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