Sql-Server

統計數據是最新的,但估計不正確

  • May 6, 2019

當我這樣做時,dbcc show_statistics ('Reports_Documents', PK_Reports_Documents)我得到報告 ID 18698 的以下結果:

在此處輸入圖像描述

對於此查詢:

SELECT * 
FROM Reports_Documents 
WHERE ReportID = 18698 option (recompile)

PK_Reports_Documents我得到了一個查詢計劃,可以按預期進行聚集索引搜尋。

但令我困惑的是估計行數的錯誤值:

在此處輸入圖像描述

據此:_

當範例查詢 WHERE 子句值等於直方圖的 RANGE_HI_KEY 值時,SQL Server 將使用直方圖中的 EQ_ROWS 列來確定等於的行數

這也是我所期望的方式,但在現實生活中似乎並非如此。我還嘗試了一些其他RANGE_HI_KEY值,這些值存在於由提供的直方圖中show_statistics並經歷了相同的情況。在我的情況下,這個問題似乎會導致一些查詢使用非常不理想的執行計劃,從而導致幾分鐘的執行時間,而我可以通過查詢提示讓它在 1 秒內執行。

總而言之:有人可以解釋一下為什麼EQ_ROWS直方圖沒有用於估計行數,錯誤估計來自哪裡?

更多(可能有幫助)資訊:

  • 自動創建統計資訊已開啟,所有統計資訊都是最新的。
  • 被查詢的表大約有 8000 萬行。
  • PK_Reports_Documents是由ReportID INT和組成的組合 PKDocumentID CHAR(8)

該查詢似乎總共載入了 5 個不同的統計對象,所有這些對像都包含ReportID表中的其他一些列。它們都經過了全新的更新。RANGE_HI_KEY下表中是直方圖中的最高上限列值。

+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
|                                  name                                   | stats_id | auto_created | user_created | Leading column Type | RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS  | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
| PK_Reports_Documents                                                    |        1 |            0 |            0 | Stationary          |        18722 | 0          | 2228,526 |                   0 | 1              |
| _dta_index_Reports_Documents_42_1629248859__K1_K63_K14_K13_K22_K23_72_6 |       62 |            0 |            0 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_1_59                                             |       76 |            0 |            1 | Stationary          |        18686 | 50,56393   | 1        |                   0 | 13397,04       |
| _dta_stat_1629248859_1_22_14_18_12_6                                    |       95 |            0 |            1 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_7_14_4_23_62                                     |       96 |            0 |            1 | Stationary          |        18698 | 56,63327   | 21641,5  |                   0 | 14526,44       |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+

sp_updatestats計劃每晚執行以更新統計資訊。

有一個簡單的解決方案:

放棄所有_dta_...統計數據並停止盲目應用 DTA 建議。

更多資訊

特別的問題是有問題的列有多組統計數據。額外的dta統計資訊是通過對數據進行採樣創建的(與索引無關的統計資訊的預設行為)。

與抽樣統計數據的情況一樣,生成的直方圖並未涵蓋基礎數據的全部範圍。問題中的查詢碰巧選擇了一個在直方圖之外的值,導致 1 行估計。

當同一列存在多組統計資訊時查詢優化器的確切行為沒有完整記錄。它確實傾向於比抽樣更喜歡“全掃描”統計數據,但它也更喜歡最近更新的統計數據而不是舊的統計數據。

引用自:https://dba.stackexchange.com/questions/93900