MS SQL 統計信息淺析上篇


統計信息概念

    統計信息是一些對象,這些對象包含在表或索引視圖中一列或多列中的數據分布有關的統計信息。數據庫查詢優化器使用這些統計信息來估計查詢結果中的基數或行數。 通過這些基數估計,查詢優化器可以生成高質量的執行計划。 例如,查詢優化器可以使用基數估計選擇索引查找運算符而不是耗費更多資源的索引掃描運算符,從而提高查詢性能。[參考MSDN]

    其實如果你以前沒有接觸過統計信息,你可以將其看做是數據庫為了得到最優的執行計划,統計數據庫里面表、索引等對象的一些數據,例如表的記錄數、所有列的平均長度、直方圖....等一些優化器需要用到的數據信息。SQL查詢優化器是一個基於成本的優化器,類似於ORACLE里面的CBO,那么優化器如果要得到成本最低的執行計划,就需要收集獲取其生成執行計划的參考依據(統計信息數據)

如果你對這些概念性的東西比較模糊的話,那么為了讓你形象的認識一下統計信息,請看下圖:

clip_image002

 

統計信息參數

     數據庫的統計信息相關參數有三個: 自動創建統計信息(Auto Create Statistics)、自動更新統計信息(Auto Update Statistics)、自動異步更新統計信息(Auto Update Statistics Asynchronously),它們都是數據庫級別的。

自動創建統計信息(Auto Create Statistics

該參數指定數據庫是否自動創建缺少的優化統計信息。如果設置為True,則將在優化過程中自動生成優化查詢需要但缺少的所有統計信息。當開啟自動創建統計信息(Auto Create Statistics)選項時,查詢優化器會對在謂詞中使用到的列,如果這些列的統計信息不可用或缺少時,則會單獨對每列創建統計信息。這些統計信息對創建一個查詢計划非常必要。它們創建於那些現有統計對象中不存在直方圖的列上,名字包括列名和對象ID的十六進制格式:_WA_Sys_<column_name>_<XXXX>。這些統計信息用於查詢優化器決定使用何種優化后的執行計划。

自動更新統計信息(Auto Update Statistics


該參數指定數據庫是否自動更新過期的優化統計信息。如果設置為True,則將在優化過程中自動生成優化查詢需要但已過期的所有統計信息。否則不自動更新統計信息。

自動異步更新統計信息(Auto Update Statistics Asynchronously

如果設置為 True,則啟動過期統計信息的自動更新,查詢在編譯前不會等待統計信息被更新。后續查詢將使用可用的已更新統計信息。如果設置為 False,則啟動過期統計信息的自動更新的查詢將等待,直到更新的統計信息可在查詢優化計划中使用。將該選項設置為 True 不會產生任何影響,除非自動更新統計信息也設置為 True

關於這三個參數,一般建議開啟自動創建統計信息、自動更新統計信息選項,關閉自動異步更新統計信息。

    1:對於自動創建統計信息選項,因為統計信息對查詢優化器至關重要,沒有統計信息,也就失去了它基於成本的優化器的意義,成為無土之木、無源之水。

    2:對於自動更新統計信息選項,有時候過期的統計信息會導致嚴重的性能問題,我都碰到過好幾起因為過時統計信息導致SQL查詢性能問題的案例,就像錯誤的地圖、錯誤的導航、錯誤的指路會讓你偏離目的地那樣,過時的統計信息往往導致查詢優化器選擇了次優的執行計划,產生糟糕的性能問題,所以這個參數必須開啟。

    3:對於自動異步更新統計信息選項,這個選項在OLTP環境下很有用,但在數據倉庫中有負面影響。至於是否開啟,我建議是關閉。默認也是關閉的。不知道這種觀念是否正確。

下面是MSDN給予的使用同步更新統計信息\異步更新統計信息的參考意見:

------------------------------------------------------------------------------------------------------------------------

在以下情況下應考慮使用同步統計信息:

· 您執行會更改數據分布的操作,例如截斷表或對很大百分比的行執行大容量更新。如果您在完成該操作后未更新統計信息,則使用同步統計信息將確保對更改的數據執行查詢前統計信息是最新的。

在以下情況下,考慮使用異步統計信息來實現可預測性更高的查詢響應時間:

· 您的應用程序頻繁執行相同的查詢、類似的查詢或類似的緩存查詢計划。與同步統計信息更新相比,使用異步統計信息更新時您的查詢響應時間可能具有更高的可預測性,因為查詢優化器可以執行傳入的查詢而不必等待最新的統計信息。這避免延遲某些查詢,而不延遲其他查詢。有關查找類似查詢的詳細信息,請參閱使用查詢和查詢計划哈希值查找和優化類似查詢

· 您的應用程序遇到了客戶端請求超時,這些超時是由於一個或多個查詢正在等待更新后的統計信息所導致的。在某些情況下,等待同步統計信息可能會導致應用程序因過長超時而失敗。

------------------------------------------------------------------------------------------------------------------------

那么先看一下如何通過SQL來查看這三個參數的設置值:

Code Snippet
  1. SELECT  name ,
  2.         is_auto_create_stats_on ,
  3.         is_auto_update_stats_async_on ,
  4.         is_auto_close_on
  5. FROM    sys.databases ;
  6.  
  7.  
  8.  
  9.  
  10. SELECT  CASE WHEN DATABASEPROPERTYEX('DBMonitor', 'IsAutoCreateStatistics') = 1
  11.              THEN 'Yes'
  12.              ELSE 'No'
  13.         END AS 'IsAutoCreateStatistics' ,
  14.         CASE WHEN DATABASEPROPERTYEX('DBMonitor', 'IsAutoUpdateStatistics') = 1
  15.              THEN 'Yes'
  16.              ELSE 'No'
  17.         END AS 'IsAutoUpdateStatistics' ,
  18.         CASE WHEN DATABASEPROPERTYEX('DBMonitor', 'Is_Auto_Update_stats_async_on') = 1
  19.              THEN 'Yes'
  20.              ELSE 'No'
  21.         END AS 'IsAutoUpdateStatsaAyncOn'
  22.  
  23. GO

那么這三個參數的值保存在哪里呢?其實只要你稍微花一點心思去研究一下,就會發現其實它是保存在系統表[sys].[sysdbreg]里面,[sys].[sysdbreg]是內部表,默認情況下不可查看,一般你可以通過系統視圖sys.database查看和研究其值的出處。

Code Snippet
  1. SET QUOTED_IDENTIFIER ON
  2. SET ANSI_NULLS ON
  3. GO
  4. CREATE VIEW sys.databases AS
  5.  SELECT d.name, d.id AS database_id,
  6.         r.indepid AS source_database_id,
  7.         d.sid AS owner_sid,
  8.         d.crdate AS create_date,
  9.         d.cmptlevel AS compatibility_level,
  10.         convert(sysname, CollationPropertyFromID(p.cid, 'name')) AS collation_name,
  11.         p.user_access, ua.name AS user_access_desc,
  12.         sysconv(bit, d.status & 0x400) AS is_read_only,        -- DBR_RDONLY
  13.         sysconv(bit, d.status & 1) AS is_auto_close_on,        -- DBR_CLOSE_ON_EXIT
  14.         sysconv(bit, d.status & 0x400000) AS is_auto_shrink_on,-- DBR_AUTOSHRINK
  15.         p.state, st.name AS state_desc,
  16.         sysconv(bit, d.status & 0x200000) AS is_in_standby,    -- DBR_STANDBY
  17.         sysconv(bit, d.status & 0x40000000) AS is_cleanly_shutdown, -- DBR_CLEANLY_SHUTDOWN
  18.         sysconv(bit, d.status & 0x80000000) AS is_supplemental_logging_enabled,-- DBR_SUPPLEMENT_LOG
  19.         p.snapshot_isolation_state, si.name AS snapshot_isolation_state_desc,
  20.         sysconv(bit, d.status & 0x800000) AS is_read_committed_snapshot_on,-- DBR_READCOMMITTED_SNAPSHOT
  21.         p.recovery_model, ro.name AS recovery_model_desc,
  22.         p.page_verify_option, pv.name AS page_verify_option_desc,
  23.         sysconv(bit, d.status2 & 0x1000000) AS is_auto_create_stats_on,        -- DBR_AUTOCRTSTATS
  24.         sysconv(bit, d.status2 & 0x40000000) AS is_auto_update_stats_on,       -- DBR_AUTOUPDSTATS
  25.         sysconv(bit, d.status2 & 0x80000000) AS is_auto_update_stats_async_on, -- DBR_AUTOUPDSTATSASYNC
  26.         sysconv(bit, d.status2 & 0x4000) AS is_ansi_null_default_on,           -- DBR_ANSINULLDFLT
  27.         sysconv(bit, d.status2 & 0x4000000) AS is_ansi_nulls_on,               -- DBR_ANSINULLS
  28.         sysconv(bit, d.status2 & 0x2000) AS is_ansi_padding_on,                -- DBR_ANSIPADDING
  29.         sysconv(bit, d.status2 & 0x10000000) AS is_ansi_warnings_on,           -- DBR_ANSIWARNINGS
  30.         sysconv(bit, d.status2 & 0x1000) AS is_arithabort_on,                  -- DBR_ARITHABORT
  31.         sysconv(bit, d.status2 & 0x10000) AS is_concat_null_yields_null_on,    -- DBR_CATNULL
  32.         sysconv(bit, d.status2 & 0x800) AS is_numeric_roundabort_on,           -- DBR_NUMEABORT
  33.         sysconv(bit, d.status2 & 0x800000) AS is_quoted_identifier_on,         -- DBR_QUOTEDIDENT
  34.         sysconv(bit, d.status2 & 0x20000) AS is_recursive_triggers_on,         -- DBR_RECURTRIG
  35.         sysconv(bit, d.status2 & 0x2000000) AS is_cursor_close_on_commit_on,   -- DBR_CURSCLOSEONCOM
  36.         sysconv(bit, d.status2 & 0x100000) AS is_local_cursor_default,         -- DBR_DEFLOCALCURS
  37.         sysconv(bit, d.status2 & 0x20000000) AS is_fulltext_enabled,           -- DBR_FTENABLED
  38.         sysconv(bit, d.status2 & 0x200) AS is_trustworthy_on,                  -- DBR_TRUSTWORTHY
  39.         sysconv(bit, d.status2 & 0x400) AS is_db_chaining_on,                  -- DBR_DBCHAINING
  40.         sysconv(bit, d.status2 & 0x08000000) AS is_parameterization_forced,    -- DBR_UNIVERSALAUTOPARAM
  41.         sysconv(bit, d.status2 & 64) AS is_master_key_encrypted_by_server,     -- DBR_MASTKEY
  42.         sysconv(bit, d.category & 1) AS is_published,
  43.         sysconv(bit, d.category & 2) AS is_subscribed,
  44.         sysconv(bit, d.category & 4) AS is_merge_published,
  45.         sysconv(bit, d.category & 16) AS is_distributor,
  46.         sysconv(bit, d.category & 32) AS is_sync_with_backup,
  47.         d.svcbrkrguid AS service_broker_guid,
  48.         sysconv(bit, case when d.scope = 0 then 1 else 0 end) AS is_broker_enabled,
  49.         p.log_reuse_wait, lr.name AS log_reuse_wait_desc,
  50.         sysconv(bit, d.status2 & 4) AS is_date_correlation_on,         -- DBR_DATECORRELATIONOPT
  51.         sysconv(bit, d.category & 64) AS is_cdc_enabled,
  52.         sysconv(bit, d.status2 & 0x100) AS is_encrypted,               -- DBR_ENCRYPTION
  53.         sysconv(bit, d.status2 & 0x8) AS is_honor_broker_priority_on   -- DBR_HONORBRKPRI
  54.     FROM master.sys.sysdbreg d OUTER APPLY OpenRowset(TABLE DBPROP, d.id) p
  55.     LEFT JOIN sys.syssingleobjrefs r ON r.depid = d.id AND r.class = 96 AND r.depsubid = 0-- SRC_VIEWPOINTDB
  56.     LEFT JOIN sys.syspalvalues st ON st.class = 'DBST' AND st.value = p.state
  57.     LEFT JOIN sys.syspalvalues ua ON ua.class = 'DBUA' AND ua.value = p.user_access
  58.     LEFT JOIN sys.syspalvalues si ON si.class = 'DBSI' AND si.value = p.snapshot_isolation_state
  59.     LEFT JOIN sys.syspalvalues ro ON ro.class = 'DBRO' AND ro.value = p.recovery_model
  60.     LEFT JOIN sys.syspalvalues pv ON pv.class = 'DBPV' AND pv.value = p.page_verify_option
  61.     LEFT JOIN sys.syspalvalues lr ON lr.class = 'LRWT' AND lr.value = p.log_reuse_wait
  62.     WHERE d.id < 0x7fff
  63.         AND has_access('DB', d.id) = 1
  64. GO
  65.  
  66. CREATE TABLE [sys].[sysdbreg]
  67.     (
  68.       [id] [int] NOT NULL ,
  69.       [name] [sys].[sysname] NOT NULL ,
  70.       [sid] [varbinary](85) NULL ,
  71.       [status] [int] NOT NULL ,
  72.       [status2] [int] NOT NULL ,
  73.       [category] [int] NOT NULL ,
  74.       [crdate] [datetime] NOT NULL ,
  75.       [modified] [datetime] NOT NULL ,
  76.       [svcbrkrguid] [uniqueidentifier] NOT NULL ,
  77.       [scope] [int] NOT NULL ,
  78.       [cmptlevel] [tinyint] NOT NULL
  79.     )
  80.   ON[PRIMARY]
  81. GO

修改統計信息參數

方法1

----關閉數據庫DBMonitor自動創建統計信息功能

USE [master]

GO

ALTER DATABASE [DBMonitor] SET AUTO_CREATE_STATISTICS OFF WITH NO_WAIT

GO

--開啟數據庫DBMonitor自動創建統計信息功能

USE [master]

GO

ALTER DATABASE [DBMonitor] SET AUTO_CREATE_STATISTICS ON WITH NO_WAIT

GO

--關閉數據庫DBMonitor自動更新統計信息功能

USE [master]

GO

ALTER DATABASE [DBMonitor] SET AUTO_UPDATE_STATISTICS OFF WITH NO_WAIT

GO

--啟用數據庫DBMonitor自動更新統計信息功能

USE [master]

GO

ALTER DATABASE [DBMonitor] SET AUTO_UPDATE_STATISTICS ON WITH NO_WAIT

GO

--關閉數據庫DBMonitor自動異步更新統計信息功能

ALTER DATABASE [DBMonitor] SET AUTO_UPDATE_STATISTICS_ASYNC OFF WITH NO_WAIT

GO

 

--啟用數據庫DBMonitor自動異步更新統計信息功能

ALTER DATABASE [DBMonitor] SET AUTO_UPDATE_STATISTICS_ASYNC ON WITH NO_WAIT

GO

方法2:使用SP_DBOPTION來啟用或禁用。

 

SP_DBOPTION DBMonitor, 'auto update statistics', 'ON';

SP_DBOPTION DBMonitor, 'auto update statistics', 'OFF;

 

方法3:圖形化方法啟用或禁用

對應的圖像化操作:選擇所要修改的數據庫,單擊右鍵選項”屬性“,選擇左側的”選項“,則能看到這三個參數

clip_image004

在 AUTO_UPDATE_STATISTICS 為 ON 時,您可以覆蓋數據庫范圍的統計信息更新行為,並且根據您的應用程序的要求為單獨的表、索引或列將自動統計信息更新設為關閉。在 AUTO_UPDATE_STATISTICS 為 ON 時,您可以通過以下方式為表、索引或列禁用和重新啟用自動統計信息更新:

· 使用 SP_AUTOSTATS 系統存儲過程。這可以禁用或重新啟用表或索引的統計信息更新。

· 對於 UPDATE STATISTICS 語句指定 NORECOMPUTE 選項。若要重新啟用統計信息更新,請重新運行 UPDATE STATISTICS,但不使用

· NORECOMPUTE 選項。

· 對於 CREATE STATISTICS 語句指定 NORECOMPUTE 選項。若要重新啟用統計信息更新,請使用 DROP STATISTICS 刪除統計信息,然后運行 CREATE STATISTICS 但不使用 NORECOMPUTE 選項。

· 對 CREATE INDEX 語句指定 STATISTICS_NORECOMPUTE 選項。若要重新啟用統計信息更新,您可以運行 ALTER INDEX 且 STATISTICS_NORECOMPUTE = OFF。

· 在 AUTO_UPDATE_STATISTICS 為 OFF 時,不能為單獨的表、索引或列將自動更新設為打開。重新啟用自動統計信息更新將還原AUTO_UPDATE_STATISTICS 選項指定的行為。如果 AUTO_UPDATE_STATISTICS 選項為OFF,統計信息更新將不會發生。

 

創建統計信息

如何創建統計信息呢,如果選項自動創建統計信息(Auto Create Statistics)開啟了,那么數據庫會自動創建某些統計信息,另外你也可以通過CREATE STATISTICS 語句手動創建某些統計信息。先看下面的例子:

USE [DBMonitor]

GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Test]') AND type in (N'U'))

DROP TABLE [dbo].[Test]

GO

SELECT * INTO Test FROM sys.objects;

此時你會看到表Test根本沒有統計信息,那么我們在表Test上創建一個索引IDX_TEST_OBJECT_ID

CREATE INDEX IDX_TEST_OBJECT_ID ON dbo.Test(object_id);

此時,你刷新一下表Test的統計信息,你會發現多了一個名為“IDX_TEST_OBJECT_ID”的統計信息,你新建多少條索引,在統計信息下就會創建與索引同名的統計信息。

SELECT DISTINCT TYPE FROM dbo.Test ;

執行上面面腳本后,我刷新統計信息,會發現多了一個名為“_WA_Sys_00000006_023D5A04”的統計信息,截圖如下:

clip_image006

那么自動創建統計信息的規律或規則是啥呢?或者理解為:什么時候數據庫創建統計信息,其實創建統計信息的規則如下:

    1:在索引創建時,SQL SERVER 會自動地在索引所在的列上創建統計信息

    2:當SQL SERVER想要使用某些列上的統計信息,發現沒有時,SQL SERVER會自動創建統計信息(前提是要開啟自動創建統計信息)。例如上面統計DISTINCT TYPE。

    3:手工使用CREATE STATISTICS之類的語句手工創建需要的統計信息。

關於CREATE STATISTICS的語法,大家可以參考MSDN,這里不做闡述了。需要注意的是統計信息可以通過全表掃描或隨機抽樣應讀取的數據百分比或指定的數據行數,收集統計信息

更新統計信息

隨着數據庫的DML操作,數據的變更會導致統計信息過期,那么這時就需要更新統計信息。通常數據庫通過兩種方式更新統計信息:

    1:如果開啟了自動更新統計信息(Auto Update Statistics)或自動異步更新統計信息選項,那么數據庫會自動更新統計信息。

    2:手動更新統計信息

更新統計信息確保查詢使用最新的統計信息編譯。不過,更新統計信息會導致查詢重新編譯。我們建議不要太頻繁地更新統計信息,因為需要在改進查詢計划和重新編譯查詢所用時間之間權衡性能。此類特定的性能權衡取決於您的應用程序。

那么數據庫什么時候、什么條件下才會更新統計信息呢?

1、 在一個空表中有數據的改動。

2、 當統計信息創建時,表的行數只有500或以下,且后來統計對象中的引導列的更改次數大於500.

3、 當表的統計信息收集時,超過了500行,且統計對象的引導列后來更改次數超過500+表總行數的20%時。

4、 在Tempdb中的表,少於6行且最少有6行被更改

注意:數據庫不會為表變量收集統計信息,所以數據量比較大時盡量不要使用表變量。

一般建議不要太頻繁地更新統計信息,因為需要在改進查詢計划和重新編譯查詢所用時間之間權衡性能。 這種特定的性能權衡取決於您的應用程序。

手工更新統計信息,一般使用 UPDATE STATISTICS 或存儲過程 sp_updatestats 來更新統計信息。

sp_autostats:顯示或更改特定索引或統計信息的自動 UPDATE STATISTICS 設置,或者顯示和更改當前數據庫中指定表或索引視圖的所有索引和統計信息的自動 UPDATE STATISTICS 設置

  顯示表的所有索引的當前狀態

    USE DBMonitor;

    GO

    EXEC sp_autostats 'dbo.test';

  啟用表的所有索引的自動統計信息

    USE DBMonitor;

    GO

    EXEC sp_autostats 'dbo.test','ON'

  禁用特定索引的自動統計信息

    USE DBMonitor;

    GO

    EXEC sp_autostats 'dbo.test','OFF', 'IDX_TEST_OBJECT_ID';

 

查看統計信息

如果要了解具體的統計信息內容,那么我們首先要知道如何查看具體的統計信息,統計信息保存在那些系統視圖里面,如果能很好的回答這兩個問題,那么我想你也就能知道統計信息的具體內容是那些了。關於第二個問題,后面章節部分再做探討。

查看統計信息,我們先由淺入深,由簡單到復雜。

sp_helpstats :返回指定表中列和索引的統計信息。

USE DBMonitor;

GO

EXEC sp_helpstats 'test' ,'ALL'

下面我們看看sys.sp_helpstats的腳本

SET QUOTED_IDENTIFIER ON

SET ANSI_NULLS ON

GO

CREATE PROCEDURE sys.sp_helpstats
    @objname NVARCHAR(776) , -- the table to check for statistics
    @results NVARCHAR(5) = 'STATS' -- 'ALL' returns indexes & stats, 'STATS' returns just stats
AS -- PRELIM

    SET nocount ON

    DECLARE @objid INT , -- the object id of the table
        @indid SMALLINT , -- the index id of an index
        @indname SYSNAME ,
        @keys NVARCHAR(2078) ,-- string build index key list, length = (16*max_id_length)+(15*2)
        @dbname SYSNAME ,
        @i INT ,
        @thiskey SYSNAME ,
        @curs CURSOR

-- Check to see that the object names are local to the current database.

    SELECT  @dbname = PARSENAME(@objname, 3)

    IF @dbname IS NULL 
        SELECT  @dbname = DB_NAME()

    ELSE 
        IF @dbname <> DB_NAME() 
            BEGIN

                RAISERROR(15250,-1,-1)

                RETURN (1)

            END

-- Check to see the the table exists and initialize @objid.

    SELECT  @objid = OBJECT_ID(@objname, 'local')

    IF @objid IS NULL 
        BEGIN

            RAISERROR(15009,-1,-1,@objname,@dbname)

            RETURN (1)

        END

    IF UPPER(@results) <> 'STATS'
        AND UPPER(@results) <> 'ALL' 
        BEGIN

            RAISERROR(N'Invalid option: %s', 1, 1, @results)

            RETURN (1)

        END

    IF UPPER(@results) = 'STATS' 
        BEGIN

            SET @curs = cursor local fast_forward READ_ONLY for

select stats_id, name from sys.stats

where object_id = @objid

and IndexProperty(@objid, name, 'IsStatistics') = 1 -- User created & auto-created stats

        END

    ELSE 
        BEGIN

            SET @curs = cursor local fast_forward READ_ONLY for

select stats_id, name from sys.stats

where object_id = @objid -- Indexes, User created & auto-created stats

        END

    OPEN @curs

    FETCH @curs INTO @indid, @indname

-- IF NO STATISTICS, QUIT

    IF @@fetch_status < 0 
        BEGIN

            DEALLOCATE @curs

            IF UPPER(@results) = 'STATS' 
                BEGIN

                    RAISERROR(15574,-1,-1) --'Object does not have any statistics.'

                END

            ELSE 
                BEGIN

                    RAISERROR(15575,-1,-1) --'Object does not have any indexes or statistics.'

                END

            RETURN (0)

        END

-- create temp table

    CREATE TABLE #spstattab
        (
          stats_name SYSNAME COLLATE database_default
                             NOT NULL ,
          stats_keys NVARCHAR(2078) COLLATE database_default
                                    NOT NULL
        )

-- Now check out each statistics set, figure out its keys and

-- save the info in a temporary table that we'll print out at the end.

    WHILE @@fetch_status >= 0 
        BEGIN

-- First we'll figure out what the keys are.

            SELECT  @keys = INDEX_COL(@objname, @indid, 1) ,
                    @i = 2 ,
                    @thiskey = INDEX_COL(@objname, @indid, 2)

            WHILE ( @thiskey IS NOT NULL ) 
                BEGIN

                    SELECT  @keys = @keys + ', ' + @thiskey ,
                            @i = @i + 1

                    SELECT  @thiskey = INDEX_COL(@objname, @indid, @i)

                END

-- INSERT ROW FOR INDEX

            INSERT  INTO #spstattab
            VALUES  ( @indname, @keys )

-- Next index

            FETCH @curs INTO @indid, @indname

        END

    DEALLOCATE @curs

-- DISPLAY THE RESULTS

    SELECT  'statistics_name' = stats_name ,
            'statistics_keys' = stats_keys
    FROM    #spstattab
    ORDER BY stats_name

    RETURN (0) -- sp_helpstats

----------------------- sp_helptext ----------------------------------------

    RAISERROR(15339,-1,-1,'sys.sp_helptext')

GO
View Code

 

2:查看統計信息一般用DBCC SHOW_STATISTICS命令,如下所示

DBCC SHOW_STATISTICS('TEST', 'IDX_TEST_OBJECT_ID'); 

Name    Updated     Rows   Rows Sampled  Steps  Density     Average key length String Index Filter Expression           Unfiltered Rows
------------------------------------------------- ------------------
IDX_TEST_OBJECT_ID   09 24 2013  9:06PM   59                   59                   41     1             4                  NO           NULL   59

(1 行受影響)

All density   Average Length Columns
------------- -------------- ---------------------------------------
0.01694915    4              object_id

(1 行受影響)

RANGE_HI_KEY RANGE_ROWS    EQ_ROWS       DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
------------ ------------- ------------- -------------------- --------------
          0             1             0                    1
          1             1             1                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          1             1             1                    1
          1             1             1                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          1             1             1                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          1             1             1                    1
          0             1             0                    1
          0             1             0                    1
          2             1             2                    1
          2             1             2                    1
          1             1             1                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1
          1             1             1                    1
          1             1             1                    1
          1             1             1                    1
          1             1             1                    1
          0             1             0                    1
          0             1             0                    1
          1             1             1                    1
          0             1             0                    1
          1             1             1                    1
          1             1             1                    1
          1             1             1                    1
          0             1             0                    1
          0             1             0                    1
          0             1             0                    1

(41 行受影響)

DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。

 

雖然查看統計信息很容易,但是要讀懂並能讀取一些信息那們就不是那么簡單的了。

列名

描述說明

Name

統計信息對象名稱

Update

上一次更新統計信息的日期和時間

Rows

在目標索引、統計信息或列中的總行數。如果篩選索引或統計信息,此行數可能小於表的行數。

Rows Sampled

用於統計信息計算的抽樣總行數。

Steps

統計信息對象第一個鍵列的直方圖中的值范圍數。每個步驟包括在直方圖結果中定義的 RANGE_ROWS 和 EQ_ROWS。

Density

查詢優化器不使用此值。顯示此值的唯一目的是為了向后兼容。密度的計算公式為 1 / distinct rows,其中 distinct rows 是直方圖輸出中所有步驟的 DISTINCT_RANGE_ROWS 之和。如果對行進行抽樣,distinct rows 則基於抽樣行的直方圖值。

Average Key Length

統計信息對象的鍵列中,所有抽樣值中的每個值的平均字節數

String Index

如果為“是”,則統計信息中包含字符串摘要索引,以支持為 LIKE 條件估算結果集大小。僅當第一個鍵列的數據類型為charvarcharncharnvarcharvarchar(max)nvarchar(max)textntext 時,才會對此鍵列創建字符串索引。

Filter Expression

包含在統計信息對象中的表行子集的表達式。NULL = 未篩選的統計信息。有關詳細信息,請參閱篩選統計信息。

Unfiltered Rows

應用篩選器表達式前表中的總行數。如果 Filter Expression 為 NULL,Unfiltered Rows 等於行標題值。

下表對指定 DENSITY_VECTOR 時結果集中所返回的列進行了說明。

列名

說明

All Density

針對統計信息對象中的列的每個前綴計算密度(1/ distinct_rows)。密度包含所有抽樣行中的非重復行,包括帶有直方圖邊界點的行。結果為每個密度顯示一行。例如,如果統計信息對象包含鍵列 (A, B, C),結果將報告 (A)、(A,B) 以及 (A, B, C) 的密度。非重復行具有一個不同的列值向量。對於列 (A,B,C),兩個不同的向量值的示例為 (4,5,6) 和 (4,5,7)。對於 (A,B),相同的兩行具有一個不同的向量值 (4,5)。對於 (A),存在一個不同的值 (4)。

Average Length

每個列前綴的列值向量的平均長度(按字節計)。例如,如果列前綴為列 A 和 B,則長度為列 A 和列 B 的字節之和。

Columns

為其顯示 All densityAverage length 的前綴中的列的名稱。

下表對指定 HISTOGRAM 選項時結果集中所返回的列進行了說明。

列名

說明

RANGE_HI_KEY

直方圖步驟的上限值。

RANGE_ROWS

表中位於直方圖步驟內(不包括上限)的行的估算數目。

EQ_ROWS

表中值與直方圖步驟的上限值相等的行的估算數目。

DISTINCT_RANGE_ROWS

直方圖步驟內(不包括上限)非重復值的估算數目。

AVG_RANGE_ROWS

直方圖步驟內(不包括上限)重復值的頻率或平均數目(如果 DISTINCT_RANGE_ROWS > 0,則為 RANGE_ROWS / DISTINCT_RANGE_ROWS)。

統計直方圖用作在查詢執行計划中查詢優化器的選擇依據

圖形化查看

image

刪除統計信息

DROP STATISTICS 刪除當前數據庫的指定表中的多個集合的統計信息。

    DROP STATISTICS Test._WA_Sys_00000006_023D5A04;

需要注意的是不能用DROP STATISTICS 刪除有關索引的統計信息。統計信息的保留時間與索引存在的時間相同,當你刪除索引時,對應的統計信息也自動刪除。如下所示:

DROP STATISTICS Test.IDX_TEST_OBJECT_ID

消息 3739,級別 11,狀態 1,第 1 行

無法對索引 'Test.IDX_TEST_OBJECT_ID' 執行 DROP,因為該索引不是統計信息集合。

 

參考資料:

  http://technet.microsoft.com/zh-cn/library/ms190397(v=sql.105).aspx

http://technet.microsoft.com/zh-cn/library/ms187348.aspx
http://blog.csdn.net/dba_huangzj/article/details/8041267
http://blog.csdn.net/zhaowenzhong/article/details/6276878

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM