Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Administration (2000)
 Automate DBCC DBREINDEX on tables

Author  Topic 

rkc01
Starting Member

43 Posts

Posted - 2002-08-07 : 13:25:21
I'm trying to write a script that will automatically exec DBCC DBREINDEX only on tables that fall below a certain scan density. This is for the 6.5 platform. On 2000 it's fairly easy but for 6.5 I can't figure out how to write the output from SHOWCONTIG to a multicolumn table so that I can look for indid, scan density, etc... Perhaps I'm looking at this the wrong way but I don't want to reindex all my tables if only a handful need it, (Our tables are pretty large and many have 6-10 non clustered in addition). Perhaps I could write the output into a single column table and then parse the rows for the info, but this just seems to awkward. Any ideas? Thanks guys.

rob

jasper_smith
SQL Server MVP & SQLTeam MVY

846 Posts

Posted - 2002-08-07 : 15:07:11
Here's one I used to use back on SQL7, should work on 6.5 although I don't know - before my time You can remove the bit that creates the clustered indexes on GEM_DBKEY as that was just for our paticular applications. Also - to take my own advice I shouldn't have really queried the system tables directly but hey I was young


CREATE PROCEDURE sp_dodefrag
AS

/* sp_dodefrag Version 1.1
J.Smith
01/06/01

Description :
This procedure should be run in the context of a specific database.
It builds a list of all user tables for the database and then uses a cursor
to step through each table and uses OSQL to run DBCC SHOWCONTIG
against each tables and insert the results into a temporary table #OSQLOutput
The output is then parsed to find the Scan Density. If this is below 80% then
the table is checked for a clustered index. If one exists it is rebuilt using
DBCC REINDEX otherwiswe one is created on GEM_DBKEY and then
dropped. THe rebuilding of the clustered index should help alleviate any
fragmentation in the tables data and index pages thus leading to quicker index
scans and table scans.

Revisions
1.1 Added rowcount to filter out low count tables 05/06/01

*/
set nocount on
--get a list of all user tables in the database
--1.1
--that have more than 300 rows
--below this fragmentation is exagerated
--and has minimal impact on traversing data
--or index pages and extents
--
DECLARE TableList CURSOR FOR

select s.name from sysobjects as s
join sysindexes as i on s.id=i.id
where s.xtype='U'
and s.name <> 'dtproperties'
and i.indid < 2
and i.rows >400
order by s.name
--declare variable to store table name
Declare @table varchar(50)

OPEN TableList
FETCH NEXT FROM TableList INTO @table
WHILE @@FETCH_STATUS <> -1
BEGIN

declare @SQL varchar(2000),
@TBID int,
@ScanDensity numeric(5,2)
--
-- get table id required for DBCC SHOWCONTIG
--
set @TBID = object_id(@table)
--
--create temporary table for storing outputs
--
create table #OSQLOutput
(OutputLine varchar(255) null)
--
--build the fragmentation command
--
select @SQL = 'dbcc showcontig(' + convert(varchar(10),@TBID) + ')'
--
-- Format osql command
--
select @SQL = 'osql /E /d '+ db_name() + ' /S' + @@servername + ' /w512 /Q"' + @SQL + '"'
--
insert into #OSQLOutput (OutputLine)
exec master.dbo.xp_cmdshell @SQL
--
-- Extract results from output
--
select @ScanDensity = convert(numeric(15,2),
substring(OutputLine,charindex('.:',OutputLine) + 2,
charindex('%',OutputLine) - charindex('.:',OutputLine)-2))
from #OSQLOutput
where OutputLine like '%Scan Density _Best Count:Actual Count_%'
--
--clear temporary table
--
drop table #OSQLOutput
--
--Check defrag level
--
If @ScanDensity < 80.00
begin
print @table + ' requires defragmenting because of Scan Density of '+ cast(@ScanDensity as varchar)
--Check for existing clustered index
if exists (select id from dbo.sysindexes where id = object_id(@table) and indid=1)
begin
DBCC DBREINDEX(@table) with NO_INFOMSGS
end
else
--Otherwise create one on GEM_DBKEY and then drop it
begin
print 'Creating clustered index on GEM_DBKEY'
declare @indexstr varchar(255), @dropstr varchar(255)
set @indexstr=('CREATE CLUSTERED INDEX ZZ ON ' + @table + '(GEM_DBKEY) WITH FILLFACTOR=90')
exec(@indexstr)
DBCC DBREINDEX(@table) with NO_INFOMSGS
set @dropstr=('DROP INDEX ' + @table + '.ZZ')
exec(@dropstr)
end
end
--else
--print @table + ' does not require defragmenting at this time'

FETCH NEXT FROM TableList INTO @table
END
--Cleanup objects
CLOSE TableList
DEALLOCATE TableList




HTH
Jasper Smith
Go to Top of Page

efelito
Constraint Violating Yak Guru

478 Posts

Posted - 2002-08-07 : 15:28:53
There's a great script for this written specifically for 6.5 here as well.

http://www.mssqlserver.com/scripts/sp__defrag.sql

Jeff Banschbach
Consultant, MCDBA
Go to Top of Page

rkc01
Starting Member

43 Posts

Posted - 2002-08-07 : 15:36:04
Thanks Jasper, I'll give it a look through and let you know how it goes.

rob

p.s.

In 6.5 I query sys tables all the time. Even in 7.0 and 2000 if the information schema views don't have what I need

Go to Top of Page

rkc01
Starting Member

43 Posts

Posted - 2002-08-07 : 15:40:16
quote:

There's a great script for this written specifically for 6.5 here as well.

http://www.mssqlserver.com/scripts/sp__defrag.sql

Jeff Banschbach
Consultant, MCDBA




Thanks Jeff, I should have thought to look on Mike's site, It's always loaded with good stuff.

Go to Top of Page
   

- Advertisement -