1. 程式人生 > 其它 >重建SQLSERVER索引

重建SQLSERVER索引

查詢碎片率

SELECT a.index_id ,B.name [IndexName] ,avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats ( DB_ID() , NULL , NULL, NULL, NULL ) AS A
JOIN sys.indexes AS B ON a.object_id = b.object_id AND a.index_id = b.index_id
inner JOIN sys.tables AS C ON a.object_id=C.object_id
inner JOIN sys.schemas AS
D ON C.schema_id=D.schema_id WHERE a.index_id > 0 order by avg_fragmentation_in_percent desc

執行

exec [P_BatchRebuildIndex] @Scheme=null,@TableName=null,@IndexName=null,@FragmentPercent=20

P_BatchRebuildIndex 建立指令碼:

/****** Object: StoredProcedure [dbo].[P_BatchRebuildIndex] Script Date: 2022/5/11 14:00:25 *****
*/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Create date: <2017-07-01> -- Description: <批量重建索引> -- EXEC P_BatchRebuildIndex 'dbo','','',30 -- ============================================= Create proc [dbo].[P_BatchRebuildIndex] --@DataBase nvarchar(50)=null,--資料庫名稱,必輸項
@Scheme nvarchar(50)=null,--架構名稱 @TableName nvarchar(50)=null, --要重建索引的表名稱,為空表示所有表 @IndexName nvarchar(200)=null ,--要重建的索引名稱 @FragmentPercent decimal(10,5)=0 --碎片率為多少以上的需要重建 AS BEGIN DECLARE @Sql nvarchar(2000); DECLARE @RebuildSql nvarchar(2000); DECLARE @ERROR nvarchar(500); DECLARE @Tables table(TableName nvarchar(100), Indexid int,IndexName nvarchar(200), FragmentPercent decimal(10,5)); ----判斷資料庫是否存在 --IF DB_ID(@DataBase) is null --BEGIN -- RAISERROR('資料庫不存在,請輸入正確的資料庫名稱!',16,1); -- RETURN -1; --END --判斷架構是否存在 IF isnull(@Scheme,'')<>'' and SCHEMA_ID(@Scheme) is null BEGIN RAISERROR('架構不存在,請輸入正確的架構名稱!',16,1); RETURN -1; END --表存不存在 IF isnull(@TableName,'')<>'' BEGIN --有架構 IF isnull(@Scheme,'')<>'' and SCHEMA_ID(@Scheme) is null BEGIN IF OBJECT_ID(@Scheme+'.'+@TableName) is null BEGIN SET @ERROR='表不存在,請輸入正確的表名稱!' RAISERROR(@ERROR,16,2); RETURN -1; END END --沒有架構 IF not exists(select 1 from sys.tables as A where A.name=@TableName ) BEGIN SET @ERROR='表不存在,請輸入正確的表名稱!' RAISERROR(@ERROR,16,5); RETURN -1; END END --索引存不存在 IF isnull(@IndexName,'')<>'' BEGIN IF not exists(select 1 from sys.SysObjects where name=@IndexName and (xtype=N'UQ' OR xtype=N'PK') ) BEGIN RAISERROR('索引不存在,請輸入正確的索引名稱!',16,3); RETURN -1; END END --如果表名為空表示所有表,如果索引為空表示所有索引 --預設查詢所有表,所有索引,所有百分比 SET @Sql='SELECT D.name+''.''+object_name(a.object_id) [TableName] ,a.index_id ,B.name [IndexName] ,avg_fragmentation_in_percent FROM sys.dm_db_index_physical_stats ( DB_ID() , NULL , NULL, NULL, NULL ) AS A JOIN sys.indexes AS B ON a.object_id = b.object_id AND a.index_id = b.index_id inner JOIN sys.tables AS C ON a.object_id=C.object_id inner JOIN sys.schemas AS D ON C.schema_id=D.schema_id WHERE a.index_id > 0 ' IF isnull(@Scheme,'') <>'' BEGIN SET @Sql +=' and D.name= '''+@Scheme+''' '; END IF isnull(@TableName,'')<>'' BEGIN SET @Sql +=' and object_name(a.object_id)= '''+@TableName+''' '; END IF isnull(@IndexName,'')<>'' BEGIN SET @Sql +=' and B.name= '''+@IndexName+''' '; END IF isnull(@FragmentPercent,0)>0 BEGIN SET @Sql +=' and avg_fragmentation_in_percent>= '+convert(nvarchar(10),@FragmentPercent)+' '; END INSERT INTO @Tables EXEC (@Sql) select '重建前',* from @Tables DECLARE cur cursor for select TableName, IndexName from @Tables OPEN cur DECLARE @tbName NVARCHAR(100),@IXName NVARCHAR(200) FETCH NEXT FROM cur INTO @tbName,@IXName WHILE(@@fetch_status=0) BEGIN SET @RebuildSql='alter index ['+@IXName+'] on '+@tbName+' rebuild' --要加上[],否則索引裡有空格會報錯 EXEC (@RebuildSql) print @RebuildSql FETCH NEXT FROM cur INTO @tbName,@IXName END CLOSE cur DEALLOCATE cur --重建後查詢 delete @Tables INSERT INTO @Tables EXEC (@Sql) select '重建後',* from @Tables Print N'執行完畢!'; return 0; END GO