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