如何修复sql server中的碎片索引?

时间:2015-12-26 10:58:21

标签: sql-server indexing fragment dbcc

我想在sql server中对表进行碎片整理,我使用此代码来了解碎片索引:

sELECT dbschemas.[name] as 'Schema',
dbtables.[name] as 'Table',
dbindexes.[name] as 'Index',
 indexstats.avg_fragmentation_in_percent as Fragmentation, 
 indexstats.page_count
  FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) 
  AS indexstats INNER JOIN sys.tables dbtables on dbtables.[object_id] =  indexstats.[object_id] 
 INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id] 
 INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]
 AND indexstats.index_id = dbindexes.index_id 
 WHERE indexstats.database_id = DB_ID() ORDER BY    indexstats.avg_fragmentation_in_percent
 desc 

在我使用了

之后的结果
 DBCC INDEXDEFRAG([MAIL SYSTEMS],EmpMail)

对碎片整理的索引然后重复使用第一个代码来显示结果,它在解密之前显示相同但没有删除任何页面? 这有什么不对,如何修复索引?

2 个答案:

答案 0 :(得分:0)

尝试此代码,这将根据碎片级别对所有索引进行碎片整理。

SELECT CASE
         WHEN indexstats.avg_fragmentation_in_percent > 5
              AND indexstats.avg_fragmentation_in_percent <= 30 THEN 'ALTER INDEX [' + ind.NAME + '] ON ['
                                                                     + Object_name(ind.OBJECT_ID)
                                                                     + '] REORGANIZE ; '
         ELSE 'ALTER INDEX [' + ind.NAME + '] ON ['
              + Object_name(ind.OBJECT_ID) + '] REBUILD; '
       END,
       'GO'
FROM   sys.Dm_db_index_physical_stats(Db_id(), NULL, NULL, NULL, NULL) indexstats
       INNER JOIN sys.indexes ind
               ON ind.object_id = indexstats.object_id
                  AND ind.index_id = indexstats.index_id
WHERE  indexstats.avg_fragmentation_in_percent > 10
       AND ind.NAME IS NOT NULL
ORDER  BY indexstats.avg_fragmentation_in_percent DESC

答案 1 :(得分:0)

这是StackUser脚本的修改版本,该脚本直接执行生成的命令,并另外打印有关已处理索引及其碎片状态的漂亮信息消息:

DECLARE @sql VARCHAR(MAX) =
(
    SELECT CASE
        WHEN indexstats.avg_fragmentation_in_percent > 5
         AND indexstats.avg_fragmentation_in_percent <= 30
        THEN
            'PRINT ''Reorganizing index [' + ind.name + '] ON [' + OBJECT_NAME(ind.object_id) + '] with ' +
            CAST(indexstats.avg_fragmentation_in_percent AS VARCHAR(10)) + ' % fragmentation ...''; ' +
            'ALTER INDEX [' + ind.name + '] ON [' + OBJECT_NAME(ind.object_id) + '] REORGANIZE ; '
        ELSE
            'PRINT ''Rebuilding index [' + ind.name + '] ON [' + OBJECT_NAME(ind.object_id) + '] with ' +
            CAST(indexstats.avg_fragmentation_in_percent AS VARCHAR(10)) + ' % fragmentation ...''; ' +
            'ALTER INDEX [' + ind.name + '] ON [' + OBJECT_NAME(ind.object_id) + '] REBUILD; '
        END
    FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats
    INNER JOIN sys.indexes ind
        ON ind.object_id = indexstats.object_id AND ind.index_id = indexstats.index_id
    WHERE indexstats.avg_fragmentation_in_percent > 10 AND ind.name IS NOT NULL
    ORDER BY indexstats.avg_fragmentation_in_percent DESC
    FOR XML PATH('')
);
EXEC (@sql)

此外,MSDN中有一个类似的脚本:https://docs.microsoft.com/de-de/sql/t-sql/database-console-commands/dbcc-indexdefrag-transact-sql?view=sql-server-ver15