indexes whose scan densities fall below a specified threshold, @magfrag, which
is passed to the SP. This SP was initially based on a code sample in SQL Server 2000
Books Online.
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
-- Declare cursor
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
FETCH NEXT
FROM tables
INTO @tableidchar
BEGIN
-- Do the showcontig of all indexes of the table
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
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
BEGIN
SET QUOTED_IDENTIFIER ON
', ' + RTRIM(@indexname) + ') WITH NO_INFOMSGS'
SELECT 'Now executing: '
SELECT(@execstr)
EXEC (@execstr)
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
@numberofrows int = 10000,
@percentchange int = 15,
@samplerate int = 10
AS
SET NOCOUNT ON
(
id int identity(1, 1),
TableName sysname,
IndexName sysname
)
@tablename nvarchar(100),
@indexname nvarchar(150),
@sql nvarchar(4000)
SELECT TableName = OBJECT_NAME(id),
IndexName = name
FROM sysindexes with ( nolock )
WHERE OBJECTPROPERTY(id, 'IsSystemTable') = 0
AND indid > 0
AND indid < 255
AND rowcnt > @numberofrows
AND CAST(rowmodctr as numeric(9, 0))
/ CAST(rowcnt as numeric(9, 0)) * 100 > @percentchange
from @StatsUpdate
begin
@indexname = IndexName
from @StatsUpdate
where id = @max
print 'Updating Statistics for ' + @tablename + ' ' + @indexname
select @sql = 'UPDATE STATISTICS ' + @tablename + ' '
+ @indexname + char(13) + ' WITH SAMPLE '
+ CONVERT(nvarchar(3), @samplerate) + ' PERCENT'
EXEC sp_executesql @sql
select @max = @max - 1
end
--------------------------------->SP END update stats