Sql-Server
手動創建索引碎片
有沒有人有一個很好的方法來手動創建索引的特定碎片,理想情況下不增加基礎表中的行數?我需要這個來進行索引重建基準測試。為了測量指定同一表/索引的碎片率所需的時間,我必須重新創建我想嘗試的特定碎片級別。
使用或多或少的隨機表更新來創建這種碎片非常耗時且困難。有任何想法嗎?
更新:這是我的測試表。它實際上有大約 540K 行,
USE [Test] GO /****** Object: Table [dbo].[tFrag2] Script Date: 12/22/2015 15:33:51 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[tFrag2]( [a] [int] NULL, [b] [varchar](1000) COLLATE Latin1_General_CI_AS NULL, [c] [varchar](1000) COLLATE Latin1_General_CI_AS NULL, [d] [decimal](18, 0) NULL, [e] [int] NULL, [uid] [uniqueidentifier] NOT NULL, [dt1] [datetime] NULL, [dt2] [datetime] NULL, [dt3] [datetime] NULL, [dt4] [datetime] NULL, [dt5] [datetime] NULL, [dt6] [datetime] NULL, [dt7] [datetime] NULL, [dt8] [datetime] NULL, [dt9] [datetime] NULL, [nv1] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [nv2] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [nv8] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [nv3] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [nv4] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [nv5] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [nv6] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [nv7] [nvarchar](4000) COLLATE Latin1_General_CI_AS NULL, [lfd] [int] IDENTITY(1,1) NOT NULL, CONSTRAINT [PK_tFrag2] PRIMARY KEY CLUSTERED ( [uid] 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 SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_a] DEFAULT ((123123)) FOR [a] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_b] DEFAULT ('ccccccccccccccccccc4444444444444444444444444') FOR [b] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_c] DEFAULT ('ffffffffffffffffffffffffffffffffffffffffffffffff') FOR [c] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_d] DEFAULT ((7)) FOR [d] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_e] DEFAULT ((777)) FOR [e] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag_uid2] DEFAULT (newid()) FOR [uid] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt1] DEFAULT (getdate()) FOR [dt1] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt2] DEFAULT (getdate()) FOR [dt2] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt3] DEFAULT (getdate()) FOR [dt3] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt4] DEFAULT (getdate()) FOR [dt4] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt5] DEFAULT (getdate()) FOR [dt5] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt6] DEFAULT (getdate()) FOR [dt6] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt7] DEFAULT (getdate()) FOR [dt7] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt8] DEFAULT (getdate()) FOR [dt8] GO ALTER TABLE [dbo].[tFrag2] ADD CONSTRAINT [DF_tFrag2_dt9] DEFAULT (getdate()) FOR [dt9] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxxx') FOR [nv1] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxx') FOR [nv2] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxx') FOR [nv8] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxx') FOR [nv3] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxx') FOR [nv4] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxx') FOR [nv5] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxx') FOR [nv6] GO ALTER TABLE [dbo].[tFrag2] ADD DEFAULT ('xxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxx') FOR [nv7] GO
對於一個索引,沒有。對於數據庫中的索引,是的:創建一個表並執行循環以創建一堆記錄並擴大數據庫。然後放下桌子。現在,縮小數據文件(根據 Paul Randal 的說法非常非常愚蠢)。
我很快就輸入了這個東西……這個傻瓜真的很管用,但是……很慢。有什麼想法嗎?
(dbo.FragStat 是查詢該表的分片值的視圖)
Create procedure dbo.fragIt @FragDest int = 10 as SET Statistics IO OfF SET Statistics Time OfF SET nocount on declare @fragPercent int = 0 declare @cntr int = 0 While @FragDest > @fragPercent Begin select @fragPercent = avg_fragmentation_in_percent from dbo.FragStat Where NameOfTable = 'tFrag2' AND ALLOC_unit_type_desc = 'IN_ROW_DATA' set @cntr = @cntr + DATEPART(MS, GETDATE()) + 1000 Update tFrag2 SET nv1 = REPLICATE('X', 1000), nv2 = REPLICATE('Y', 1000), nv3 = REPLICATE('Y', 1000) WHERE LFD = @cntr or LFD = @cntr + 135 OR LFD = @cntr + 240 OR LFD = @cntr + 545 OR LFD = @cntr + 657 OR LFD = @cntr + 784 OR LFD = @cntr + 854 End print 'destination frag of ' + cast(@FragDest as varchar(3)) + ' reached: ' + cast(@fragPercent as varchar(3))