索引维护存储过程(作业调用)
/*===================================
--author: fan
--Date: 2008-08-08
--Description: 定期对表的索引进行重建操作
--注意:要观察索引的情况,对于不经常用的索引可以删除。
--注意:小表字段可以不用创建索引。
===========================================*/
CREATE PROCEDURE [dbo].[Y_RebuildIndex]
AS
BEGIN
DECLARE @t TABLE(id INT IDENTITY(1,1),TableName VARCHAR(200),IndexName VARCHAR(500),rate INT,[type] INT);
DECLARE @i INT,@n INT;
DECLARE @TableName VARCHAR(200),@IndexName VARCHAR(500),@rate INT;
DECLARE @sql VARCHAR(MAX),@type INT;
INSERT INTO @t(TableName,IndexName,rate,[type])
-- 查看当前库所有表的索引碎片情况
SELECT
object_name(a.[object_id]) AS [TableName]
,NAME AS [IndexName]
,avg_fragmentation_in_percent AS rate
,[type]
FROM sys.dm_db_index_physical_stats
(
DB_ID() -- 当前数据库
, NULL
, NULL, NULL, NULL
) AS a
JOIN sys.indexes AS b
ON a.[object_id] = b.[object_id] AND a.index_id = b.index_id
AND NAME > '' AND avg_fragmentation_in_percent > 10 /*排除非常低的碎片级别*/
ORDER BY [Type];/*先创建聚集索引再创建非聚集索引*/
SET @i = 1;
SELECT @n = COUNT(1) FROM @t;
WHILE (@i <= @n)
BEGIN
SET @TableName = '';
SET @IndexName = '';
SET @sql = '';
SET @type = 0;
SET @rate = 0;
SELECT @TableName = TableName,@IndexName = IndexName,@type = [type],@rate = rate FROM @t WHERE id = @i;
IF @TableName > '' AND @IndexName > ''
BEGIN
-- 聚积索引或碎片率低于30,则采用索引组织方式进行维护
IF @type = 1 OR @rate < 30
BEGIN
SET @sql = 'ALTER INDEX ' + @IndexName + ' ON ' + @TableName + ' REORGANIZE;';
END
-- 非聚积索引并且碎片率超过30,才使用重建索引方式
ELSE
BEGIN
SET @sql = 'ALTER INDEX ' + @IndexName + ' ON ' + @TableName + ' REBUILD;';
/*重新生成索引 除非采用ALTER INDEX REBUILD WITH (ONLINE = ON) 联机方式才不锁表*/
/* 无法重新组织表 "%3!" 的索引 "%1!" (分区 %2!),因为已禁用页级锁定。
SET @sql = '
ALTER INDEX ' + @index_name + ' ON [' + @table_name + '] SET (ALLOW_PAGE_LOCKS = ON);
ALTER INDEX ' + @index_name + ' ON [' + @table_name + '] REORGANIZE;';
*/
END
EXEC (@sql);
END
SET @i = @i + 1;
END
END