2009-11-17 92 views
1

我們有TABLE A按日期進行分區,並且不包含今天的數據,它只包含前一天的數據,並且還包含年初至今的數據。SQL Server 2005查詢計劃優化器在日期分區表上窒息

我們已經將表B按照包含今天的數據以及從前一天到今年的數據進行分區。上表B的頂部有它連接針對View_CView_D和左外聯接表E. View_CView_D從1個表中的每個選擇和不具有任何其它表連接在一個視圖,View_B所以View_B看起來像

SELECT b.Foo, c.cItem, d.dItem, E.eItem 
FROM TABLE_B b JOIN View_C c on c.cItem = b.cItem 
JOIN View_D d on b.dItem = d.dItem 
LEFT OUTER JOIN TABLE_E on b.eItem = e.eItem 

View_AB在提取日期以及另一個約束條件下加入表A和View_B。所以它看起來是這樣的:

SELECT a.Col_1, b.Col_2, ... 
FROM TABLE_A a LEFT OUTER JOIN View_B b 
on a.ExtractDate = b.ExtractDate and a.Foo=b.Foo 

-- no where clause 

當從超過前一天的任何其他數據搜索,查詢分析器做什麼預期和做了哈希匹配連接,完成外連接,並讀取約116頁價值來自表B的數據。然而,如果在前一天運行,查詢優化器會嚇倒並使用嵌套連接,掃描表7000次以上並在連接中讀取8,000,000多頁。

我們可以通過使用聯接提示來僞造/強制它使用不同的查詢計劃,但是會導致視圖中的任何約束都會導致優化器拋出查詢無法處理的錯誤由於加入提示而完成。

編輯以添加pages/scans =與先前運行優化程序正確選擇散列而不是嵌套連接的前一天運行的掃描相同的編號。

正如評論所說,我們嚴厲通過創建TABLE_B覆蓋索引覆蓋在View_B的加入降低了衝擊,但IO仍然高於這將是,如果優化器選擇正確的計劃,特別是因爲除了前幾天的搜索之外,該指數基本上是多餘的。

該sqlplan是在http://pastebin.com/m53789da9,抱歉,它不是格式很好的版本。

+0

任何機會,你可以發佈每個.sqlplan,所以我們可以看到差異? – chadhoc 2009-11-17 14:34:25

+0

是由ExtractDate聚集的兩個表嗎? ExtractDate上的非覆蓋非聚集索引也可能導致此行爲(即使使用分區)。 – 2009-11-17 16:08:20

+0

這些表也由ExtractDate聚類,A和B之間的連接標準應該由表上的索引覆蓋。我們通過在連接標準上創建一個覆蓋索引來緩解了這個問題。在最佳連接中,它仍然會執行更多的頁面讀取操作,但這是可以接受的。 – Rebthor 2009-11-18 14:44:16

回答

1

如果你能張貼每個查詢的.sqlplan這將有助於確定,但我的預感是,你之前的當天日期查詢時,並嵌套循環是可能得到一個並行計劃對錶中包含的分區進行常量循環,然後爲每個分區產生一個工作線程(有關此的更多信息,請參閱SQLCAT post on parallel plans with partitioned tables in Sql2005)。但是,如果沒有看到計劃,則無法驗證是否是這種情況。

+0

SQL 2k8 QO在分區方面的表現要好得多 – 2009-11-17 16:06:48

+1

是的,雖然給予標題我假設2005 ... – chadhoc 2009-11-17 16:25:48

+0

我不認爲這是什麼原因造成這裏的問題,雖然這是一個非常有趣的閱讀。使用OPTION(MAXDOP 1)運行仍然使查詢優化器在數百萬頁IO中徘徊。 看起來,優化器正在部分地被綁定到nesteed視圖上。 – Rebthor 2009-11-17 21:53:08

0

如果有人遇到過這種情況,問題似乎只與切分方案有切線關係。即使我們在夜間運行統計信息更新,它出現的SQL Server

  1. 沒有對ExtractDate創建統計
  2. 即使將該明確創建提取日期統計,未有起色,在現有一天有數據。

我們通過執行CREATE STATISTICS TABLE_A_ExtractDate_Stats ON TABLE_A WITH FULLSCAN來解決它。現在搜索前一天和隨機抽樣的幾天似乎會產生正確的計劃。