--创建索引脚本
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;