Monday, September 13, 2010

MSSQL Index Report as a stored procedure

--Added the output of dbcc show_statistics to determine whether sampled or fullscan

CREATE PROCEDURE sp_index_report AS
        SET NOCOUNT ON
        IF OBJECT_ID ('tempdb.dbo.#stats_header') IS NOT NULL
            BEGIN
                DROP TABLE #stats_header
            END
        CREATE TABLE #stats_header
        (
            index_name VARCHAR (255),
            updated VARCHAR (255),
            rows VARCHAR (255),
            sampled VARCHAR (255),
            steps VARCHAR (255),
            density VARCHAR (255),
            avg_key_len VARCHAR (255),
            string_index VARCHAR (255)
        )
        DECLARE object_crsr INSENSITIVE
            CURSOR FOR
            SELECT
                owner = CASE WHEN o.principal_id IS NULL THEN SCHEMA_NAME (o.schema_id)
                    ELSE SCHEMA_NAME (o.principal_id) END,
                table_name = o.name,
                index_name = i.name
            FROM
                sys.objects o,
                sys.indexes i
            WHERE
                o.object_id = i.object_id AND
                o.type = 'U' AND
                i.name IS NOT NULL
            ORDER BY o.name
            FOR READ ONLY
        DECLARE @owner_name VARCHAR (255)
        DECLARE @table_name VARCHAR (255)
        DECLARE @index_name VARCHAR (255)
        DECLARE @sqlcmd VARCHAR (1000)
        OPEN object_crsr
        FETCH object_crsr INTO
            @owner_name,
            @table_name,
            @index_name
        WHILE
            @@FETCH_STATUS = 0
            BEGIN
                SET
                    @sqlcmd =
                    ''
                SET
                    @sqlcmd =
                    'DBCC SHOW_STATISTICS ("' + @owner_name + '.' + @table_name + '",' + @index_name + ') with STAT_HEADER'
                IF @sqlcmd IS NOT NULL
                    BEGIN
                        INSERT
                            INTO #stats_header
                            EXEC (@sqlcmd)
                    END
                FETCH object_crsr INTO
                    @owner_name,
                    @table_name,
                    @index_name
            END
        CLOSE object_crsr
        DEALLOCATE object_crsr
        SELECT
            owner = CASE WHEN O.principal_id IS NULL THEN SCHEMA_NAME (O.schema_id)
                ELSE SCHEMA_NAME (O.principal_id) END,
            OBJECT_NAME (I.object_id) AS object_name,
            I.name AS index_name,
            I.type_desc,
            STATS_DATE (I.object_id, I.index_id) AS statistics_update_date,
            H.rows AS rows,
            fullscan = CASE WHEN H.rows = H.sampled THEN 'YES' WHEN H.rows IS NULL THEN '?'
                ELSE 'SAMPLED' END,
            H.steps,
            H.density,
            stats_no_recompute = CASE WHEN S.no_recompute = 1 THEN 'ON'
                ELSE 'OFF' END
        FROM
            sys.indexes I,
            sys.objects O,
            sys.stats S,
            #stats_header H
        WHERE
            O.object_id = I.object_id AND
            O.type = 'U' AND
            S.object_id = I.object_id AND
            O.object_id = S.object_id AND
            I.name = S.name AND
            H.index_name = I.name
        ORDER BY
            owner,
            object_name
        DROP TABLE #stats_header
        RETURN
go

No comments:

Post a Comment