Save output of DBCC SHOW_STATISTICS into a table

  • 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

  • Auch, didn't look at the Forum, looks like this one should be moved too

  • 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
  • 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

  • i think there must be some other way

  • 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 ?

     

     

  • 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

  • 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.

  • Re: DBCC SHOW_STATISTICS ... multiple tables

    In BOL, review the <option> argument.

Viewing 9 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic. Login to reply