--创建索引脚本 SELECT [statement] 表名称, 'CREATE INDEX [IX_' + SO.name + '_' + REPLACE( REPLACE(REPLACE(REPLACE(ISNULL(equality_columns, included_columns), '[', ''), ']', ''), ',', '_'), ' ', '' ) + '] ON ' + SO.name + '(' + ISNULL(equality_columns, '') + CASE WHEN equality_columns IS NOT NULL AND inequality_columns IS NOT NULL THEN ',' ELSE '' END + ISNULL(inequality_columns, '') + ')' + ISNULL(' INCLUDE (' + included_columns + ')', '') + ' WITH(FILLFACTOR = 90, PAD_INDEX = ON)' AS 索引创建脚本, avg_user_impact 收益百分比, avg_total_user_cost 减少成本, avg_total_user_cost * avg_user_impact * (user_scans + user_seeks) AS 综合收益 FROM sys.dm_db_missing_index_groups AS G INNER JOIN sys.dm_db_missing_index_group_stats AS GS ON G.index_group_handle = GS.group_handle INNER JOIN sys.dm_db_missing_index_details AS D ON G.index_handle = D.index_handle INNER JOIN sysobjects AS SO ON SO.id = D.object_id ORDER BY 综合收益 DESC; --索引碎片查询 SELECT t.name 表名称, i.name 索引名称, s.avg_fragmentation_in_percent 碎片百分比, CASE WHEN s.avg_fragmentation_in_percent > 30 THEN 'alter index ' + i.name + ' on dbo.' + t.name + ' rebuild' WHEN s.avg_fragmentation_in_percent > 5 THEN 'alter index ' + i.name + ' on dbo.' + t.name + ' reorganize' ELSE '无需整理' END 碎片整理脚本 FROM sys.tables t JOIN sys.indexes i ON i.object_id = t.object_id AND i.name IS NOT NULL INNER JOIN sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'limited') s ON s.object_id = i.object_id AND s.index_id = i.index_id AND s.alloc_unit_type_desc = 'IN_ROW_DATA' ORDER BY 碎片百分比 DESC; --重建索引 ALTER INDEX PK_Sys_PowerNode ON dbo.Sys_PowerNode REBUILD; --重新组织索引 ALTER INDEX PK_Sys_PowerNode ON dbo.Sys_PowerNode REORGANIZE; --使用游标重新组织指定库中的索引,消除索引碎片 SET NOCOUNT ON; --R_T层游标取出当前数据库所有表 DECLARE R_T CURSOR FOR SELECT name FROM sys.tables; DECLARE @T VARCHAR(50); OPEN R_T; FETCH NEXT FROM R_T INTO @T; WHILE @@fetch_status = 0 BEGIN --R_index游标判断指定表索引碎片情况并优化 DECLARE R_Index CURSOR FOR SELECT t.name, i.name, s.avg_fragmentation_in_percent FROM sys.tables t JOIN sys.indexes i ON i.object_id = t.object_id JOIN sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID(@T), NULL, NULL, 'limited') s ON s.object_id = i.object_id AND s.index_id = i.index_id; DECLARE @TName VARCHAR(50), @IName VARCHAR(50), @avg INT, @str VARCHAR(500); OPEN R_Index; FETCH NEXT FROM R_Index INTO @TName, @IName, @avg; WHILE @@fetch_status = 0 BEGIN IF @avg >= 30 --如果碎片大于30,重建索引 BEGIN SET @str = 'alter index ' + RTRIM(@IName) + ' on dbo.' + QUOTENAME(RTRIM(@TName)) + ' rebuild'; END; ELSE --如果碎片小于30,重新组织索引 BEGIN SET @str = 'alter index ' + RTRIM(@IName) + ' on dbo.' + QUOTENAME(RTRIM(@TName)) + ' reorganize'; END; PRINT @str; EXEC (@str); --执行 FETCH NEXT FROM R_Index INTO @TName, @IName, @avg; END; --结束r_index游标 CLOSE R_Index; DEALLOCATE R_Index; FETCH NEXT FROM R_T INTO @T; END; --结束R_T游标 CLOSE R_T; DEALLOCATE R_T; SET NOCOUNT OFF;