利用存储过程进行选择性的进行碎片整理

本文介绍了一个SQL Server存储过程,用于检测并自动整理数据库中的索引碎片。该过程分为两个阶段:首先检测所有用户表的索引碎片,然后对扫描密度低于设定阈值的索引执行碎片整理。

CREATE PROCEDURE sp_defragment_indexes @maxfrag DECIMAL

AS --王成辉翻译整理,转贴请注明出处

--声明变量

SET NOCOUNT ON

DECLARE @tablename VARCHAR (128)

DECLARE @execstr VARCHAR (255)

DECLARE @objectid INT

DECLARE @objectowner VARCHAR(255)

DECLARE @indexid INT

DECLARE @frag DECIMAL

DECLARE @indexname CHAR(255)

DECLARE @dbname sysname

DECLARE @tableid INT

DECLARE @tableidchar VARCHAR(255)

--检查是否在用户数据库里运行

SELECT @dbname = db_name()

IF @dbname IN ('master', 'msdb', 'model', 'tempdb')

BEGIN

PRINT 'This procedure should not be run in system databases.'

RETURN

END

--第1阶段:检测碎片

--声明游标

DECLARE tables CURSOR FOR

SELECT convert(varchar,so.id)

FROM sysobjects so

JOIN sysindexes si

ON so.id = si.id

WHERE so.type ='U'

AND si.indid < 2

AND si.rows > 0

-- 创建一个临时表来存储碎片信息

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 tables

-- 对数据库的所有表循环执行dbcc showcontig命令

FETCH NEXT

FROM tables

INTO @tableidchar

WHILE @@FETCH_STATUS = 0

BEGIN

--对表的所有索引进行统计

INSERT INTO #fraglist

EXEC ('DBCC SHOWCONTIG (' + @tableidchar + ') WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS')

FETCH NEXT

FROM tables

INTO @tableidchar

END

-- 关闭释放游标

CLOSE tables

DEALLOCATE tables

-- 为了检查,报告统计结果

SELECT * FROM #fraglist

--第2阶段: (整理碎片) 为每一个要整理碎片的索引声明游标

DECLARE indexes CURSOR FOR

SELECT ObjectName, ObjectOwner = user_name(so.uid), ObjectId, IndexName, ScanDensity

FROM #fraglist f

JOIN sysobjects so ON f.ObjectId=so.id

WHERE ScanDensity <= @maxfrag

AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0

-- 输出开始时间

SELECT 'Started defragmenting indexes at ' + CONVERT(VARCHAR,GETDATE())

--打开游标

OPEN indexes

--循环所有的索引

FETCH NEXT

FROM indexes

INTO @tablename, @objectowner, @objectid, @indexname, @frag

WHILE @@FETCH_STATUS = 0

BEGIN

SET QUOTED_IDENTIFIER ON

SELECT @execstr = 'DBCC DBREINDEX (' + '''' +RTRIM(@objectowner) + '.' + RTRIM(@tablename) + '''' +

', ' + RTRIM(@indexname) + ') WITH NO_INFOMSGS'

SELECT 'Now executing: '

SELECT(@execstr)

EXEC (@execstr)

SET QUOTED_IDENTIFIER OFF

FETCH NEXT

FROM indexes

INTO @tablename, @objectowner, @objectid, @indexname, @frag

END

-- 关闭释放游标

CLOSE indexes

DEALLOCATE indexes

-- 报告结束时间

SELECT 'Finished defragmenting indexes at ' + CONVERT(VARCHAR,GETDATE())

-- 删除临时表

DROP TABLE #fraglist

GO

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值