程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> Microsoft SQL Server 2000 中查詢優化器使用的統計(2)

Microsoft SQL Server 2000 中查詢優化器使用的統計(2)

編輯:關於SqlServer

  請注意,當 sp_helpindex 輸出只顯示城市統計 (City) 的一個列時,show_statistics 的輸出也會顯示 City,Customer_id 列組合的所有密度值。這是因為表中 Customer_id 列上有一個群集的索引,並且每個輔助索引也包含群集的關鍵字列。通常,這一事實對於用戶而言是透明的,但查詢優化器會了解群集的列,並且如果執行查詢只要求這些列的值在輔助索引的頂部,它會避免輔助獲取。統計也包含群集的關鍵字列。

  使用 SQL Server 2000 創建統計

  SQL Server 2000 中有兩種基本語句會生成上述統計信息:CREATE INDEX 首先會生成聲明的索引,然後,作為副產品,它會為組成索引的列組合創建一個統計集;CREATE STATISTICS 只為給定列或列的組合生成統計。

  另外,還有多種方法可以創建統計或索引,但歸根結底,每種方法都會發出上述兩個命令之一。

  使用 sp_createstats 為當前數據庫中所有用戶表的全部合格列(不包括圖像和文本數據)創建統計。如果某個列已經有了直方圖,則不會為其創建新的直方圖。

  使用 dbcc dbreindex 為指定數據庫中的表重新生成一個或多個索引。

  在查詢分析器中,鍵入一個查詢,選擇“顯示執行計劃”(Show Execution Plan),然後執行查詢。在顯示的任意圖標上單擊右鍵,並選擇“管理索引” (Manage Index)或“創建/更新統計信息”(Create/Update Statistics)。

  使用 Create Index 向導(在其他文章中說明)。

  下面是對 pubs..authors 表執行 CREATE STATISTICS 命令的一個示例:

  CREATE STATISTICS s1 ON authors (state, au_lname) WITH SAMPLE 50 PERCENT通常,按默認抽樣方式生成的統計最為理想。但有時,使用更大的樣本大小來生成統計(理想狀況下可以使用 fullscan)有助於查詢優化,例如給定列中的值分布不均勻時(某些值頻繁出現,而其他值較少出現)。使用較大的樣本大小來生成統計,必須以創建統計時所需時間的延長為代價。

  上面的命令創建一個兩列統計。在本例中,因為表太小,所以會忽略 SAMPLE 50 PERCENT 並執行完全掃描。抽樣主要用於避免過多掃描數據,並且只影響具有 1024 或更多頁面 (8 MB) 的表和索引。

  在 SQL Server 2000 中,創建索引的同時會為所有索引創建統計。SQL Server 在編譯查詢時自動創建單列統計。這些統計是為優化器必須估算密度或分發的列而創建的。這一規則有兩種例外情況:首先,當直接對表執行操作所需的代價小於創建統計所需的代價時,不能為該表創建統計;其次,當服務器過於繁忙(有大量正在進行的重要操作)時,也不能創建統計。

  為避免長時間維護未使用過的統計,SQL Server 2000 會記錄那些自動創建的統計(僅包括那些不是創建索引的副產品的統計信息)的使用時間。幾次自動更新之後,列統計會被放棄而不是被更新。如果將來需要,可以重新創建這些統計。更新統計與創建統計在代價方面並沒有實質性的差別。記錄使用時間的操作也不會影響用戶創建的統計。

  通過執行 sp_dboption dbname, 'auto create statistics', 'OFF' 可以在數據庫級禁用自動創建統計的功能。

  默認情況下,統計是在執行 CREATE STATISTICS 命令或自動創建統計時,通過對數據集進行抽樣而創建的。CREATE INDEX 總是會掃描整個數據集,因此最初創建的索引統計並不進行抽樣。CREATE STATISTICS 命令允許您通過在 WITH 子句中指定 FULLSCAN 或要掃描的數據百分比來設置樣本大小。後者被認為是一個近似值。在 UPDATE STATISTICS 命令上指定 WITH RESAMPLE 時也可以繼承上一個樣本大小。當既存在索引(通過 fullscan 統計方式創建),其他列(通過 sample 統計方式創建)上又有統計時,該方法尤其有用。隨後在 UPDATE STATISTICS 上使用 RESAMPLE 選項,將保持索引的 fullscan 統計和其他列的 sample 統計。

  dbcc show_statistics 命令在 Rows Sampled 標題下顯示樣本大小。自動創建或更新的統計總是用默認的抽樣方式生成。默認的抽樣方式是按表大小的對數函數進行抽樣,這種抽樣方式的樣本大小增長緩慢。

  SQL Server 查詢分析器也會監視自動創建統計的操作。AutoStats 事件位於 Object 跟蹤事件組中。定義該跟蹤時,也會選擇 Integer Data、Success 和 Object ID 列。一旦捕獲 AutoStats 事件,Integer Data 列將包含為給定表更新的統計數,Object ID 成為該表的 ID,而 TextData 列(默認情況下包含在跟蹤定義中)則包括列的名稱以及 Updated: 或 Created: 兩個前綴之一。Success 列包含潛在的 Failure 指示信息。在某些情況下,您可能會發現 AutoStats 事件不帶有任何創建或更新的統計。當 auto update statistics 處於關閉狀態時,會生成這類事件;或者,當表實際已經變更,而因為引用該變更表的查詢被優化而導致當時表中不存在任何索引或統計時,也會生成這類事件。

  DROP STATISTICS 命令用於放棄統計,但不能放棄創建索引時附帶生成的統計。只有將索引放棄後,才能刪除其附帶生成的統計。


  在 SQL Server 2000 中維護統計

  在表中執行了一系列 INSERT、DELETE 和/或 UPDATE 查詢後,統計可能不反映給定列或索引中數據分布的真實情況。如果某個表在上次創建或更新統計之後進行了大量的更新活動,那麼當 SQL Server 查詢優化器需要該表中某個特定列的統計時,SQL Server 會(使用 auto update statistics)通過對列中的值進行抽樣來自動更新統計。統計的自動更新由查詢優化操作觸發,並且只涉及查詢中所引用列的一個子集。SYSINDEXES 值中的 rowmodctr 列顯示了自上次創建或更新統計之後對表執行的更改次數。對於每個索引和統計集,SYSINDEXES 中都會有一個對應的行(如果表中沒有群集的索引,則會有一個與堆相對應的行),SQL Server 2000 將分別維護每個索引和統計的更改次數(但在 SQL Server 7.0 中並非這樣)。在表中執行 INSERT、UPDATE 和 DELETE 查詢時,只會為 ID 為 0 或 1 的索引(一般,每個表中只有一個)遞增 rowmodctr 值。對於其他的統計和索引,它只顯示一個必須加到索引 0 或 1 的 rowmodctr 上的相對值,通過將這兩個值相加來得到該索引中已變更的行的真實數目。

  這一邏輯使得在 INSERT、UPDATE 和 DELETE 查詢過程中,對每個表只需要維護一行中的 rowmodctr;同時,又能夠分別跟蹤每個索引中已變更的行。因此,當 auto update statistics 處於打開狀態時,只更新與給定查詢所必需的索引和列對應的行。

  查詢示例

  在表 t1 中插入 506 行,然後創建非群集的索引 i1 和 i2。進行了這些操作之後,SYSINDEXES 表中會出現有趣的條目:

  Name           Indid          rowcnt          rowmodctr
  t1             0            506            506
  i1             2            506            -506
  i2             3            506            -506

  插入了另外 213 行後,計數為:

  Name           Indid          rowcnt          rowmodctr
  t1             0            719            719
  i1             2            506            -506
  i2             3            506            -506

  使用 UPDATE STATISTICS t1 (i1) 刷新了索引 i1 的統計之後:

  Name            Indid            rowcnt            rowmodctr
  t1              0              719              0
  i1              2              506              0
  i2              3              506              213

  可以在不同的級別上將上面所說的 auto update statistics 特性關閉。

  在數據庫級別使用 sp_dboption dbname, 'auto create statistics', 'OFF'。也可以使用該 sp 來顯示特定數據庫的當前設置。

  對表、索引或統計使用 UPDATE STATISTICS 命令的 NORECOMPUTE 選項。

  對表或統計使用 CREATE STATISTICS 命令的 NORECOMPUTE 選項。

  用 sp_autostats 來顯示和更改表、索引或統計的設置。

  也可以使用 sp_dboption、UPDATE STATISTICS 或 sp_autostats 重新啟用自動更新統計,其方法與上述操作相似。


  SQL Server 2000 在每個數據庫、每個索引和表的級別上分別保存自動更新統計的設置。盡管您可以使用一條 CREATE STATISTICS 命令來打開一個表中的所有統計,但必須通過更改給定表中所有統計和索引的設置來完成該操作。表 6 顯示了不同的數據庫、表和索引設置的組合效果。

  表 6:不同的數據庫、表和索引設置的組合效果

  數據庫設置      表/索引設置     Statistics Auto Update 對該對象是否有效
   ON           ON           ON
   ON           OFF           OFF
   OFF           ON           OFF
   OFF           OFF           OFF


  自動更新統計一般通過對索引或表抽樣來執行。您可以通過手動運行 CREATE 和 UPDATE 統計來改變樣本大小。在這樣創建統計時,統計更新會被相同的 SQL 分析器事件替代。

  統計和索引的視圖

  通常,索引的視圖上不需要統計,這是因為:只有在將基礎表和索引的所有統計都附加到查詢操作之後,才會考慮替換查詢操作中的索引視圖。但是,有一點例外:如果使用 NOEXPAND 提示在 FROM 子句中直接引用視圖,就會使用統計。如果在不包含索引的視圖上使用 NOEXPAND 提示,則會生成錯誤並無法執行操作。

  因為索引視圖上的統計的用途非常有限,所以不使用 sp_createstats 在索引的視圖上創建索引,也不使用 sp_updatestats 對其進行更新。auto update 和 auto create statistics 可以用於索引的視圖。但正如前面所說,僅當在查詢中通過 NOEXPAND 提示使用索引的視圖,並且 AUTO UPDATE 或 CREATE STATISTICS 選項處於打開狀態時,優化器才需要這些統計,這些統計也才會被真正創建。您也可以在索引的視圖列上手動執行 CREATE STATISTICS,或在索引的視圖上使用 UPDATE STATISTICS 來更新列或索引統計。

  總結

  對於查詢優化器,數據庫中的數據統計是重要的輸入。默認情況下,SQL Server 自動創建和維護統計,而不需要用戶的參與。大多數 SQL Server 用戶不必更改默認值,就可以獲得最佳性能。SQL Server 提供了多個接口,用於更改默認的統計創建和維護的規則,但只有在默認規則不能達到最佳性能的特殊環境下,您才需要使用這些接口。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved