আমি কীভাবে একটি এসকিউএল সার্ভার সূচককে টুকরো টুকরো করব?


9

আমি যে এসকিউএল সার্ভার 2017 পরীক্ষা ডাটাবেসে ইচ্ছাকৃতভাবে খারাপ সূচকগুলি তৈরি করতে চাই, কেবল এই রক্ষণাবেক্ষণের স্ক্রিপ্টগুলি আরও ভালভাবে বুঝতে পারি? এসকিউএল সার্ভার সূচক এবং পরিসংখ্যান রক্ষণাবেক্ষণ

সূচকের অখণ্ডতার সাথে আপোস করার বা সূচী খণ্ডন বাড়াতে কি কোনও দ্রুত / স্বয়ংক্রিয় উপায় আছে? এটি অর্জনের জন্য আমি যে কোনও দরকারী সংস্থানটি দেখতে পারি তা কি জানেন?


আপনার সংজ্ঞা উপর নির্ভর করে কুশ্রী আপনি জগাখিচুড়ি আপ করতে পারেন ভরাট ফ্যাক্টর যা হবে আপ বিশৃঙ্খলা করবেন ফ্র্যাগমেন্টেশন, কিন্তু একটি অধ: পতিত থাকবে প্রভাবিত পাশাপাশি
scsimon

3
আপনি কি একটি সূচী বা একটি ডাটাবেসে সমস্ত সূচক চান? আপনি যদি সমস্ত সূচকের জন্য চান তবে আপনার ডাটাবেস সঙ্কুচিত করুন -DBCC SHRINKDATABASE ([yourNONProdDB])
কিন শাহ

সমস্ত ডিবি সূচকগুলি নিখুঁত হবে। ধন্যবাদ @ কিনশাহ
মোরোরো

উত্তর:


10

একটি দ্রুত উপায় যা আমি কল্পনা করতে পারি তা হল UNIQUEIDENTIFIERএকটি প্রাথমিক কী হিসাবে একটি টেবিল তৈরি করা এবং প্রচুর এলোমেলো মান .োকানো। এই স্ক্রিপ্টটি ব্যবহার করে এটি অর্জন করা যেতে পারে:

CREATE TABLE dbo.Tests (Id UNIQUEIDENTIFIER PRIMARY KEY);
GO
INSERT INTO dbo.Tests (Id)
WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n))
SELECT NEWID()
FROM x AS x1, x AS x2, x AS x3, x AS x4, x AS x5, x AS x6;

এটি মিলিয়ন সারি উত্পন্ন করবে।

যে NEWID()কোনও আদেশের গ্যারান্টি দেয় না তা জেনে এসকিউএল সার্ভারকে টেবিলের এলোমেলো দাগগুলিতে প্রবেশ করতে হবে - এটি প্রাথমিক কী খণ্ডিত হতে চলেছে।


1
এটি কাজ করবে না বা কমপক্ষে গ্যারান্টিযুক্ত নয়: এসকিউএল সার্ভার সূচকগুলিকে সূচীতে যুক্ত করার আগে সারিগুলি সারিগুলি সারি করতে পারে (সারি সংখ্যার কারণে ডিস্কে স্নুলিং প্রয়োজন) them টুকরো টুকরো করার জন্য আপনাকে অনেকগুলি ব্যক্তিগত সন্নিবেশ সম্পাদন করতে হবে - এসএসএমএসে: INSERT dbo.Tests (Id) SELECT NEWID(); GO 1000000;- এতে অবশ্যই আরও সময় লাগবে। অন্য প্রশ্নের জন্য আমি একসাথে চেকেছি এমন উদাহরণের জন্য পেস্টবিন.com/ এসভিএলটিআরএনপি দেখুন । পরিবর্তনশীল দৈর্ঘ্যের সারিগুলি ব্যবহার করা এবং এলোমেলোভাবে এগুলিকে আপডেট করা আরও দক্ষতার সাথে খণ্ড খণ্ড উত্পাদন করতে পারে?
ডেভিড স্পিলিট

3

আমি বেশ কয়েকটি "কুশলী" সূচী তৈরি করতে চেয়েছিলাম, তাই আমি নিম্নলিখিতটি করেছি। এটা ভাল কাজ করে

-- Create databases to test index job, each database is about 800MB with 100,000 GUID primary keys, in each of two tables
-- Create 6 database to test index job for DatabasesInParallel Database design based on example https://dba.stackexchange.com/q/9821/21924

--Drop last test
USE [master]
exec asp_kill_user_connections [IndexTest_1]
exec asp_kill_user_connections [IndexTest_2]
exec asp_kill_user_connections [IndexTest_3]
exec asp_kill_user_connections [IndexTest_4]
exec asp_kill_user_connections [IndexTest_5]
exec asp_kill_user_connections [IndexTest_6]
GO

DROP DATABASE [IndexTest_1]
GO
DROP DATABASE [IndexTest_2]
GO
DROP DATABASE [IndexTest_3]
GO
DROP DATABASE [IndexTest_4]
GO
DROP DATABASE [IndexTest_5]
GO
DROP DATABASE [IndexTest_6]
GO

-- create [IndexTest_1]
USE [master];
GO

CREATE DATABASE [IndexTest_1];
GO

USE IndexTest_1

SET NOCOUNT ON

CREATE TABLE TestGuidA (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestGuidB (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000


WHILE (@BatchCounter <= 20)
BEGIN 
BEGIN TRAN

DECLARE @LocalCounter INT = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidA (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @LocalCounter = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidB (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @BatchCounter +=1
COMMIT 
END

-----------------------------------------------

-- create [IndexTest_2]
USE [master];
GO

CREATE DATABASE [IndexTest_2];
GO

USE IndexTest_2

SET NOCOUNT ON

CREATE TABLE TestGuidA (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestGuidB (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000


WHILE (@BatchCounter <= 20)
BEGIN 
BEGIN TRAN

DECLARE @LocalCounter INT = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidA (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @LocalCounter = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidB (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @BatchCounter +=1
COMMIT 
END

------------------------------------

-- create [IndexTest_3]
USE [master];
GO

CREATE DATABASE [IndexTest_3];
GO

USE IndexTest_3

SET NOCOUNT ON

CREATE TABLE TestGuidA (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestGuidB (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000


WHILE (@BatchCounter <= 20)
BEGIN 
BEGIN TRAN

DECLARE @LocalCounter INT = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidA (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @LocalCounter = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidB (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @BatchCounter +=1
COMMIT 
END

----------------------------------------
-- create [IndexTest_4]
USE [master];
GO

CREATE DATABASE [IndexTest_4];
GO

USE IndexTest_4

SET NOCOUNT ON

CREATE TABLE TestGuidA (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestGuidB (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000


WHILE (@BatchCounter <= 20)
BEGIN 
BEGIN TRAN

DECLARE @LocalCounter INT = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidA (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @LocalCounter = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidB (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @BatchCounter +=1
COMMIT 
END

------------------------------------------------
-- create [IndexTest_5]
USE [master];
GO

CREATE DATABASE [IndexTest_5];
GO

USE IndexTest_5

SET NOCOUNT ON

CREATE TABLE TestGuidA (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestGuidB (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000


WHILE (@BatchCounter <= 20)
BEGIN 
BEGIN TRAN

DECLARE @LocalCounter INT = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidA (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @LocalCounter = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidB (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @BatchCounter +=1
COMMIT 
END
--------------------------------------------

-- create [IndexTest_6]
USE [master];
GO

CREATE DATABASE [IndexTest_6];
GO

USE IndexTest_6

SET NOCOUNT ON

CREATE TABLE TestGuidA (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

CREATE TABLE TestGuidB (Id UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID() PRIMARY KEY,
SomeDate DATETIME, batchNumber BIGINT, FILLER CHAR(100))

DECLARE @BatchCounter INT = 1
DECLARE @Numrows INT = 100000


WHILE (@BatchCounter <= 20)
BEGIN 
BEGIN TRAN

DECLARE @LocalCounter INT = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidA (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @LocalCounter = 0

    WHILE (@LocalCounter <= @NumRows)
    BEGIN
    INSERT TestGuidB (SomeDate,batchNumber) VALUES (GETDATE(),@BatchCounter)
    SET @LocalCounter +=1
    END

SET @BatchCounter +=1
COMMIT 
END
-------------------------------
use master
DBCC FREEPROCCACHE -- Clear plan cache for next text. 

1

সাধারণত, যখন টেবিলে থাকে Updateবা Insertঅপারেশন হয় তখন সূচক খণ্ডগুলি ঘটে ।

আপনি যদি দ্রুত ইস্যুটি তৈরি করতে চান (সূচী বিভাজন), Indexআপনার পরীক্ষার টেবিলে কম দিয়ে একটি তৈরি করুন fill factorএবং সেই টেবিলে ভারী Updateবা Insertঅপারেশন করুন। আপনি এই স্ক্রিপ্টগুলির সাথে কাজ করতে পারেন ..


1

CRYPT_GEN_RANDOMআমি এই উত্তরে যেমন করেছিলাম তেমন ব্যবহার করতে পারেন : ফিল্টার স্কিমা ইন ইনডেক্স অপ্টিমাইজ স্ক্রিপ্ট

আপনি এমন একটি সংখ্যক কলামে তথ্য সন্নিবেশ করতে পারেন যা এতে সূচিযুক্ত করে এটির মতো খণ্ডন করতে পারে:

-- Fill with random integers to create fragmentation
INSERT INTO [ProdTable] (c1, c2) VALUES  (CRYPT_GEN_RANDOM(8000), 'filler');
GO 12800

আপনার যদি প্রয়োজন হয় তবে আপনি ডেটা আপডেট করতে বা সংখ্যার পরিবর্তে একটি স্ট্রিংয়ে রূপান্তর করতে পারেন।

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