SQL Server 索引维护

本文提供了一段SQL脚本,用于检查数据库中的索引碎片,并根据碎片程度进行整理。脚本首先设置允许的最大碎片比例,然后遍历数据库中的所有表,收集每个索引的碎片信息,并据此决定采取重组或重建索引的操作。

使用以下脚本查看数据库索引碎片的大小情况:

 DBCC SHOWCONTIG  WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS

 

 

以下使用脚本来处理维护作业:

 

/*Perform a 'USE <database name>' to select the database in which to run the script.*/
-- Declare variables
SET NOCOUNT ON;
DECLARE @tablename varchar(255);
DECLARE @execstr   varchar(400);
DECLARE @objectid  int;
Declare @IndexName varchar(500);
DECLARE @indexid   int;
DECLARE @frag      decimal;
DECLARE @maxfrag   decimal;
DECLARE @TmpName   varchar(500);

-- Declare @TmpName =''
set @TmpName = ''

-- Decide on the maximum fragmentation to allow for.
SELECT @maxfrag = 30.0;

-- Declare a cursor.
DECLARE tables CURSOR FOR
   SELECT TABLE_SCHEMA + '.' + TABLE_NAME
   FROM INFORMATION_SCHEMA.TABLES
   WHERE TABLE_TYPE = 'BASE TABLE';

-- Create the table.
CREATE TABLE #fraglist (
   ObjectName char(255),
   ObjectId int,
   IndexName char(255),
   IndexId int,
   Lvl int,
   CountPages int,
   CountRows int,
   MinRecSize int,
   MaxRecSize int,
   AvgRecSize int,
   ForRecCount int,
   Extents int,
   ExtentSwitches int,
   AvgFreeBytes int,
   AvgPageDensity int,
   ScanDensity decimal,
   BestCount int,
   ActualCount int,
   LogicalFrag decimal,
   ExtentFrag decimal);

-- Open the cursor.
OPEN tables;

-- Loop through all the tables in the database.
FETCH NEXT
   FROM tables
   INTO @tablename;

WHILE @@FETCH_STATUS = 0
BEGIN;
-- Do the showcontig of all indexes of the table
   INSERT INTO #fraglist
   EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''')
      WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS');
   FETCH NEXT
      FROM tables
      INTO @tablename;
END;

-- Close and deallocate the cursor.
CLOSE tables;
DEALLOCATE tables;

-- Declare the cursor for the list of indexes to be defragged.
DECLARE indexes CURSOR FOR
   SELECT ObjectName, ObjectId,IndexName,IndexId, LogicalFrag
   FROM #fraglist
   WHERE INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0;

-- Open the cursor.
OPEN indexes;

-- Loop through the indexes.
FETCH NEXT
   FROM indexes
   INTO @tablename, @objectid, @IndexName,@indexid, @frag;


WHILE @@FETCH_STATUS = 0
 BEGIN;
   if @frag <  @maxfrag
    Begin    
       SELECT @execstr = 'ALTER INDEX  [' + RTRIM(@IndexName) + ']  ON  [' + RTRIM(@tablename) + '] REORGANIZE WITH ( LOB_COMPACTION = ON ) '
       print @maxfrag + ' ' + @execstr
     End
    else
     Begin
       SELECT @execstr = 'ALTER INDEX  [' + RTRIM(@IndexName) + ']  ON  [' + RTRIM(@tablename) + '] REBUILD  WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, SORT_IN_TEMPDB = OFF, ONLINE = OFF )'
       print  @maxfrag + ' ' + @execstr
     End     
         
    EXEC (@execstr);
    
    --更新统计信息
      IF @TmpName<>@tablename
      BEGIN
     SET @tmpName=@tableName
     PRINT 'UPDATE STATISTICS '+@TableName + ' WITH FULLSCAN '
     EXEC ('UPDATE STATISTICS '+@TableName + ' WITH FULLSCAN ')
      END


     FETCH NEXT
     FROM indexes
     INTO @tablename, @objectid, @IndexName,@indexid, @frag;
 END;

-- Close and deallocate the cursor.
CLOSE indexes;
DEALLOCATE indexes;

-- Delete the temporary table.
DROP TABLE #fraglist;
GO

### SQL Server 索引维护方法与最佳实践 #### 1. 理解索引碎片及其影响 索引碎片是指由于频繁的数据修改操作(如插入、更新和删除),导致物理存储上的数据页顺序不再连续的现象。这种现象会显著降低查询性能,尤其是在大规模读取场景下[^1]。 #### 2. 定期检测索引碎片程度 为了有效维护索引,需定期评估其碎片水平。可以通过以下 T-SQL 脚本获取索引的碎片率: ```sql SELECT OBJECT_NAME(object_id) AS TableName, name AS IndexName, avg_fragmentation_in_percent FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL , 'LIMITED') WHERE index_id > 0 AND avg_fragmentation_in_percent > 10; ``` 此脚本返回平均碎片率超过 10% 的索引列表[^3]。 #### 3. 整理或重建索引 根据索引的碎片率采取不同的措施: - **低至中度碎片 (小于 30%)**: 使用 `ALTER INDEX ... REORGANIZE` 命令重新整理索引结构。 - **高度碎片 (大于 30%)**: 使用 `ALTER INDEX ... REBUILD` 或者 `DROP` 和 `CREATE` 方法完全重建索引。 示例代码如下: ```sql -- 对指定索引进行REORGANIZE ALTER INDEX IX_ExampleIndex ON ExampleTable REORGANIZE; -- 对指定索引进行REBUILD ALTER INDEX IX_ExampleIndex ON ExampleTable REBUILD WITH (ONLINE = ON); ``` 注意,在线 (`ONLINE=ON`) 模式的重建可减少锁定时间,但可能需要更多资源[^3]。 #### 4. 自动化索引维护过程 手动维护大量索引既耗时又易出错,因此建议构建自动化解决方案。可以利用 Microsoft 提供的 Ola Hallengren 维护脚本来实现这一目标。该工具支持灵活配置,并能处理各种类型的索引维护需求[^4]。 下载地址:https://ola.hallengren.com/sql-server-index-and-statistics-maintenance.html 调用示例: ```sql EXECUTE dbo.IndexOptimize @Databases = 'USER_DATABASES', @FragmentationLow = NULL, @FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE', @FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE'; ``` #### 5. 配合其他优化策略 除了索引维护外,还需关注整体数据库健康状况。例如,通过监控查询性能指标来识别慢查询;分析等待统计信息以定位瓶颈所在;以及调整内存分配等设置提升系统响应速度[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值