對比:重建索引與更新統計

最近常常被問到的一個問題是關於在數據庫維護過程,重建索引與更新統計的執行前後次序。一般,須要考慮如下幾點,這裏注意的是有兩種統計:索引統計、列統計。html

1)默認狀況下,UPDATE STATISTICS 將會更新索引統計和列統計,若是語句中僅使用了COLUMNS選項,則只更新列統計,若僅使用了INDEX選項,則只更新索引統計數據庫

2)默認狀況下,UPDATE STATISTICS語句僅採樣表的一部分數據,使用UPDATE STATISTICS WITH FULLSCAN則會掃描全表ui

3)重建索引(如使用ALTER INDEX … REBUILD語句)僅更新索引統計,其效果至關於第2狀況(WITH FULLSCAN),重建索引不會更新任何列統計url

4)重組索引(如使用ALTER INDEX … REORGANIZE語句)不更新任何統計3d

 

綜上所述,最簡單的狀況是:重建索引並更新統計;正如上面提到的,若是重建索引,則索引統計也會經過掃描整個表的行被一同更新,那麼只需再運行UPDATE STATISTICS WITH FULLSCAN, COLUMNS語句來更新列統計。htm

既然第一步僅更新了索引統計,第二步僅更新了列統計,兩者執行的前後順序並不重要。blog

 

其餘較爲複雜的狀況是:基於碎片級的重建索引,固然,最壞的狀況:若是首先重建了索引(僅掃描整張表的方式更新了索引統計,緊接着使用UPDATE STATISTICS語句(無任何參數),則會又執行了一遍索引統計。索引

 

下面經過AdventureWorks示例數據庫爲例來介紹這些命令的工做方式。get

 

首先運行如下腳本,建立臨時表dbo.SalesOrderDetailit

SELECT * INTO dbo.SalesOrderDetail FROM sales.SalesOrderDetail

下面使用sys.stats 系統視圖來查詢新表的統計狀況。

SELECT name, auto_created, stats_date(object_id, stats_id) AS update_date FROM sys.stats WHEREobject_id = object_id('dbo.SalesOrderDetail')

 對比:重建索引與更新統計

因爲是一張新表,並沒有任何查詢,因此沒有統計結果,下面執行如下的查詢來產生一些統計:

select * from dbo.SalesOrderDetail where SalesOrderID = 43670 and OrderQty =1

 對比:重建索引與更新統計

再運行先前的查詢系統視圖的語句,咱們會發現系統爲SalesOrderID和OrderQty兩列建立了以_WA_Sys命名的兩個列統計。

 對比:重建索引與更新統計

下面再運行建立索引的語句:

create index ix_product_id on dbo.SalesOrderDetail ( ProductID)

再運行系統視圖的查詢:

 對比:重建索引與更新統計

經過上圖中的"auto_created"能夠知道哪些統計是由系統建立的,下面運行以下語句只更新列統計,能夠經過update_date列來檢查。

update statistics SalesOrderDetail with fullscan, columns

 對比:重建索引與更新統計

接着運行更新索引統計的語句:

update statistics SalesOrderDetail with fullscan, index

 對比:重建索引與更新統計

下面兩條語句的執行效果是同樣的(更新索引統計和更統計)

update statistics SalesOrderDetail with fullscan 
update statistics SalesOrderDetail with fullscan, all
對比:重建索引與更新統計

 

下面再運行索引重建的方式來進行比較:

alter index ix_product_id on dbo.SalesOrderDetail rebuild

 對比:重建索引與更新統計

 

最後咱們來運行「重組索引」檢查是否更新了統計:

ALTER INDEX ix_product_id ON dbo.SalesOrderDetail REORGANIZE

 對比:重建索引與更新統計

由此發現,執行索引重組並未更新任何統計。

相關文章
相關標籤/搜索