索引碎片维护
一、设计目标。
定期描述指定数据库中表或视图的索引碎片并对合符整理要求的索引进行REBUILD或REORGANIZE操作。
二、设计说明。
数据表在添加、更新、删除操作中会产生索引碎片,导致查询速度变慢,特别是查询大型数据表时更为明显,所以需要对某些重要的表进行定期索引扫描并针对合符要求的索引进行重组或重建工作。
整理索引碎片的方法如下:
1、Drop原来的索引再重建这些索引,这种方法的优点是索引彻底重建,达到最理想的状况。但是这此会阻塞所有的查询,最好是在索引碎片十分严重,并且使用REBUILD无法达到效果的情况下使用。注意:使用DROP_EXISTING子句,可以避免non-clustered index被重建两次。
2、ALTER INDEX ...... REORGANIZE重组索引。
使用最少系统资源重新组织索引,重新组织还会压缩索引页。可以在数据库online的情况下执行,但是整理不够彻底。
3、ALTER INDEX ...... REBUILD 重新生成索引。
重新生成索引将会删除并重新创建索引。这将根据指定的或现有的填充因子设置压缩页来删除碎片、回收磁盘空间,然后对连续页中的索引行重新排序。该方法在一个事务中完成操作,在数据文件中需要有足够的free space来满足将所有的索引及相关的一些对象进行重建,否则操作可能失败,或者是重建的不十分彻底。对于数据量非常大的表,所需的free space也更多,应当特别注意这一点。
本方法只使用REBUILD或REORGANIZE方式重建索引,对于有严重过索引碎片的表或视图,请自行Drop和重建。
查看索引碎片的方法如下:
USE IndexService3
SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL , 'LIMITED')
查看期中的avg_fragmentation_in_percent字段
三、使用说明。
因为此SP使用了SQL2005新特性,所以只能运行在兼容级别为SQL Server 2005(90)的数据库上。
1、 执行附件中的SQL脚本,在要进行碎片维护的数据库上创建存储过程dm_defragment_indexes
2、 可以建立作业定期运行或手工定期运行脚本。
3、 参数说明:
@dbName 数据库名称
@owner 所有者(默认值为dbo)
@objectList 被扫描的表或视图的列表
@baseFrag 参与重组操作的最小碎片率(默认值为10.00)
@maxFrag 参与重建操作的最小碎片率(默认值为15.00)
完整调用例子:
DECLARE @RC int
DECLARE @dbName nvarchar(256)
DECLARE @owner varchar(30)
DECLARE @objectList varchar(8000)
DECLARE @baseFrag float
DECLARE @maxFrag float
EXECUTE @RC = [IndexService3].[dbo].[dm_defragment_indexes]
@dbName = N'IndexService3'
,@owner = 'dbo'
,@objectList = 'ContentIndex,ContentTag' --'*'
,@baseFrag = 10.00
,@maxFrag = 15.00
简化调用
EXECUTE @RC = [IndexService3].[dbo].[dm_defragment_indexes]
@dbName = N'IndexService3'
,@objectList = ' ContentIndex,ContentTag ' --只写表名,并使用”,”分隔
或
EXECUTE @RC = [IndexService3].[dbo].[dbm_defragment_indexes]
@dbName = N'IndexService3'
,@objectList = '*' --扫描数据库中所有的索引
备注:
@baseFrag<frag<@maxFrag 执行REBUILD
frag>@maxFrag 执行REORGANIZE
默认值:@owner='dbo' @baseFrag=10.0 @maxFrag=15.0
设置@objectList='*' 则为扫描库中所有表或视图
4、输出说明:
1.1 < Frag < 2.1 执行索引重组; Frag >= 2.1 执行索引生成
IndexService3.dbo.ContentIndex.idx_id 索引碎片为4.98504% REBUILD索引: ALTER INDEX idx_id ON dbo.ContentIndex REBUILD 耗时:0s
IndexService3.dbo.ContentIndex.idx_guid 索引碎片为1.10939% REORGANIZE索引: ALTER INDEX idx_guid ON dbo.ContentIndex REORGANIZE 耗时:0s
IndexService3.dbo.ContentIndex.idx_createtime 索引碎片为10.2933% REBUILD索引: ALTER INDEX idx_createtime ON dbo.ContentIndex REBUILD 耗时:0s
IndexService3.dbo.ContentIndex.idx_author 索引碎片为1.10047% REORGANIZE索引: ALTER INDEX idx_author ON dbo.ContentIndex REORGANIZE 耗时:0s
输出信息说明了,重组索引或重建索引的条件,以及执行的操作和所耗费的时间和资源。
5、建议:只针对需要重点维护的表进行本方法的索引维护,因为索引的重组或重建会耗费不少了时间,并且这样可以把维护控制在可控的范围内。推荐如下方法:
DECLARE @RC int
DECLARE @dbName nvarchar(256)
DECLARE @owner varchar(30)
DECLARE @objectList varchar(8000)
DECLARE @baseFrag float
DECLARE @maxFrag float
EXECUTE @RC = [IndexService3].[dbo].[dm_defragment_indexes]
@dbName = N'IndexService3'
,@objectList = 'ContentIndex,ContentTag'
ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.zh-CHS/tsqlref9/html/b796c829-ef3a-405c-a784-48286d4fb2b9.htm
http://www.sql-server-performance.com/rd_index_fragmentation.asp
http://www.sql-server-performance.com/tp_automatic_reindexing.asp
http://www.cnblogs.com/RicCC/archive/2006/09/01/492442.html