Click here to monitor SSC
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 


Save output of DBCC SHOW_STATISTICS into a table


Save output of DBCC SHOW_STATISTICS into a table

Author
Message
SeekQuel
SeekQuel
Old Hand
Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)

Group: General Forum Members
Points: 348 Visits: 7
Hi,

At our company, we are using a single package on SQL server for Accounting and Warehousing.

We experience some performance problems and a quick look at indexing shows that there are a lot of useless columns in the indexes.

There are a lot of tables to evaluate, we would like to scan the statistics of all tables and place them in a datamart for thorough analysis.

How can we access statistics with queries, or, at least, save the DBCC SHOW_STATISTICS results into a database?

Regards,

Geert Boelens



SeekQuel
SeekQuel
Old Hand
Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)

Group: General Forum Members
Points: 348 Visits: 7
Auch, didn't look at the Forum, looks like this one should be moved too



SeekQuel
SeekQuel
Old Hand
Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)Old Hand (348 reputation)

Group: General Forum Members
Points: 348 Visits: 7
Hi guys,

Just got this one solved too.

You'll need VB to place the results in the table.

A stored procedure may return multiple results. The .NextRecordset allows to jump to the next resultset.

Just as simple as that!!!

The code is something like:

 
dim lrstResult as ADODB.Recordset
dim lconServer as ADODB.Connection

set lconServer =new adodb.connection
set lrstResult =new ADODB.Recordset

lconServer.open "whatever"
lrstresult.open "DBCC SHOW_STATISTICS ('Table','Index')",lconserver.connection

'First recordset
debug.print lrstresult.fields...

'Second recordset
set lrstresult=lrstresult.nextrecordset
debug.print lrstresult.fields...

'Third recordset
set lrstresult=lrstresult.nextrecordset
debug.print lrstresult.fields...

lrstresult.close
lconserver.close

set lrstresult=nothing
set lconserver=nothing




DanMcClain
DanMcClain
Valued Member
Valued Member (55 reputation)Valued Member (55 reputation)Valued Member (55 reputation)Valued Member (55 reputation)Valued Member (55 reputation)Valued Member (55 reputation)Valued Member (55 reputation)Valued Member (55 reputation)

Group: General Forum Members
Points: 55 Visits: 555
Try this to keep it inside SQL. I use this as a schedule job on my servers to execute against all databases /tables on the server. I execute IndexDefrag when Index defragmentation is over 30.

Comment out the IndexDefrag Code. And also store the results into a permanent table instead of a temp table.
-----------------------------------------
SET NOCOUNT ON

SELECT LTRIM(RTRIM(name)) AS 'name', 'F' AS 'flag' INTO #dbs FROM
sysdatabases WHERE name NOT IN
('tempdb')ORDER BY dbid

DECLARE @lv_db_name VARCHAR(40)

WHILE (SELECT COUNT(*) FROM #dbs WHERE flag = 'F') > 0
BEGIN
SET ROWCOUNT 1
SELECT @lv_db_name = name FROM #dbs WHERE flag = 'F'
SET ROWCOUNT 0

Print 'Database = ' + @lv_db_name
PRINT ''

EXEC ('USE [' + @lv_db_name + ']

--=================================
--Use DBCC SHOWCONTIG and DBCC INDEXDEFRAG to defragment the indexes in a database, above a declared threshold.
-- Declare variables
SET NOCOUNT ON
DECLARE @ownername VARCHAR (128)
DECLARE @tablename VARCHAR (128)
DECLARE @execstr VARCHAR (255)
DECLARE @objectid INT
DECLARE @indexid INT
DECLARE @frag DECIMAL
DECLARE @maxfrag DECIMAL

-- Decide on the maximum fragmentation to allow
SELECT @maxfrag = 30.0

-- Declare cursor
DECLARE tables CURSOR FOR
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = ''BASE TABLE''

-- Create the table
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 the cursor
OPEN tables

-- Loop through all the tables in the database
FETCH NEXT
FROM tables
INTO @ownername,@tablename

WHILE @@FETCH_STATUS = 0
BEGIN
-- Do the showcontig of all indexes of the table
INSERT INTO #fraglist
EXEC (''DBCC SHOWCONTIG (['' + @ownername + ''.'' + @tablename + ''])
WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS'')

FETCH NEXT
FROM tables
INTO @ownername,@tablename
END

-- Close and deallocate the cursor
CLOSE tables
DEALLOCATE tables

-- Declare cursor for list of indexes to be defragged
DECLARE indexes CURSOR FOR
SELECT ObjectName, ObjectId, IndexId, LogicalFrag
FROM #fraglist
WHERE LogicalFrag >= @maxfrag
AND INDEXPROPERTY (ObjectId, IndexName, ''IndexDepth'') > 0

-- Open the cursor
OPEN indexes

-- loop through the indexes
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag

WHILE @@FETCH_STATUS = 0
BEGIN
PRINT ''Executing DBCC INDEXDEFRAG (0, '' + RTRIM(@tablename) + '','' +
RTRIM(@indexid) + '') - fragmentation currently ''
+ RTRIM(CONVERT(varchar(15),@frag)) + ''%''
SELECT @execstr = ''DBCC INDEXDEFRAG (0, '' + RTRIM(@objectid) + '',
'' + RTRIM(@indexid) + '')''
EXEC (@execstr)

FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexid, @frag
END

-- Close and deallocate the cursor
CLOSE indexes
DEALLOCATE indexes

-- Delete the temporary table
DROP TABLE #fraglist
')

UPDATE #dbs
SET flag = 'T'
WHERE name = @lv_db_name
END

DROP TABLE #dbs
SET NOCOUNT OFF



manojsoni2001
manojsoni2001
Forum Newbie
Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)

Group: General Forum Members
Points: 7 Visits: 1
i think there must be some other way



manojsoni2001
manojsoni2001
Forum Newbie
Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)Forum Newbie (7 reputation)

Group: General Forum Members
Points: 7 Visits: 1

Hi,

one solution for your problem is to create the temporary table with the same fields which is displayed in output of DBCC SHOW_STATISTICS

then run the following script.

INSERT INTO #temptable
EXEC ('DBCC SHOW_STATISTICS (''' + @tablename + ''',''' + @indexname + ''')

is it ok as according to u r requirement ?





Simon.Hughes
Simon.Hughes
Forum Newbie
Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)

Group: General Forum Members
Points: 3 Visits: 6
He was after show_statistics, not contig. These list two very different results sets. Key difference here: Statistics returns multiple tables as part of it's results set. Contig returns only one.

Formatting the results of statistics into a table is achievable by dropping the output into a file. You then have the option to skim through the file, record by record to extract the data you need, but it's not an ideal solution by any means.

I may look for a quick alternative shortly
Simon.Hughes
Simon.Hughes
Forum Newbie
Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)Forum Newbie (3 reputation)

Group: General Forum Members
Points: 3 Visits: 6
Yep.. had q quick look. I'd recommand dynamic sql - use a while loop to work through your objects to pull stats back from.

create table #nextobject (record varchar(200))

Within the loop:

exec master..xp_cmdshell 'osql -d yourdatabase -q "dbcc show_statistics(yourtable,''yourindex'')" -o c:\sqltempout.txt -E'

bulk insert #entirefile from 'c:\sqltempout.txt' with (rowterminator = '')



Now all you need to do is locate the relevant line which should be simple enough with a patindex etc.

Have fun.
Your Name Here
Your Name Here
SSC-Enthusiastic
SSC-Enthusiastic (158 reputation)SSC-Enthusiastic (158 reputation)SSC-Enthusiastic (158 reputation)SSC-Enthusiastic (158 reputation)SSC-Enthusiastic (158 reputation)SSC-Enthusiastic (158 reputation)SSC-Enthusiastic (158 reputation)SSC-Enthusiastic (158 reputation)

Group: General Forum Members
Points: 158 Visits: 792
Re: DBCC SHOW_STATISTICS ... multiple tables

In BOL, review the <option> argument.
Go


Permissions

You can't post new topics.
You can't post topic replies.
You can't post new polls.
You can't post replies to polls.
You can't edit your own topics.
You can't delete your own topics.
You can't edit other topics.
You can't delete other topics.
You can't edit your own posts.
You can't edit other posts.
You can't delete your own posts.
You can't delete other posts.
You can't post events.
You can't edit your own events.
You can't edit other events.
You can't delete your own events.
You can't delete other events.
You can't send private messages.
You can't send emails.
You can read topics.
You can't vote in polls.
You can't upload attachments.
You can download attachments.
You can't post HTML code.
You can't edit HTML code.
You can't post IFCode.
You can't post JavaScript.
You can post emoticons.
You can't post or upload images.

Select a forum

































































































































































SQLServerCentral


Search