2010-12-20 64 views
6

我們有一個比較複雜的SQL更新查詢,每月運行幾次。大多數情況下,它似乎運行速度非常快,但在某些數據庫中,這需要很長時間。在涉及的表上運行「UPDATE STATISTICS」之後,更新立即再次快速運行。我們最終設置了一個夜間任務,在數據庫中的所有表上調用UPDATE STATISTICS。但是這似乎並沒有解決問題。我們仍然不得不每次手動運行「UPDATE STATISTICS」。爲什麼統計數據會這麼快就過時了?爲什麼統計信息在SQL Server中如此快速過時?

這裏的大約查詢的樣子:

UPDATE DataTableA 
SET DataTableA.IndexedColumn1 = 123456789, DataTableA.Flag1 = 1 
FROM DataTableA WITH (INDEX(IX_DataTableA)) 
INNER JOIN GroupingTableA ON GroupingTableA.ForeignKey1 = GroupingTableA.PrimaryKey 
INNER JOIN LookupTableA ON DataTableA.ForeignKey3 = LookupTableA.PrimaryKey 
LEFT OUTER JOIN GroupingTableB ON DataTableA.IndexedColumn2 = GroupingTableB.IndexedColumn2 
WHERE GroupingTableB.IndexedColumn1 = 123456789 
AND DataTableA.IndexedColumn1 IS NULL 
AND DataTableA.IndexedColumn2 IN (... 300 entries here ...) 
AND DataTableA.Deleted = 0 
AND GroupingTableA.Date <= GroupingTableB.EndDate 
AND GroupingTableA.Date >= DATEADD(month, -1, GroupingTableB.StartDate) 
AND LookupTableA.Column2 = 1 
AND DataTableA.Status1 IN (1, 3) 
AND DataTableA.Status2 NOT IN (1, 3, 9) 

DataTableA包含數百萬行的。
GroupingTableA和GroupingTableB每個都包含數以萬計的行。
LookupTableA包含數十行。
指數IX_DataTableA是(IndexedColumn1 ASC,IndexedColumn2 ASC)的索引

+0

通過試驗和錯誤,我們確定上例中的GroupingTableB是過期的。問題仍然存在,但是我們每次插入時都會在該表上調用「UPDATE STATISTICS」來解決這個問題。不完全是理想的解決方案... – 2011-06-28 15:15:07

+0

我知道這個問題很陳舊,但是對於它的價值,在WHERE子句中將條件放在GroupingTableB上的那一刻,它將其「LEFT JOIN」邏輯地轉換爲「INNER JOIN '。你有3個這樣的條件。如果你想讓'LEFT JOIN'實際上作爲一個適當的'OUTER'連接,那麼這些條件必須移動到'LEFT JOIN'中的'ON'子句。我只是在說'... :) – ErikE 2013-01-12 03:31:42

回答

3

我不認爲,如果你強迫它使用一個特定的索引統計信息將作爲重要得多(WITH (INDEX(IX_DataTableA))

你確定知道的比優化好?

我會通過查看快速更新和更新慢的執行計劃開始。此外,被記錄的數量正在更新可比的快/慢查詢?

+0

好的電話@Abe Miessler - @Bryce Wagner在更新統計信息後可能會看到改進,因爲UDPATE使用新的執行計劃。 – bobs 2010-12-20 23:30:52

+0

在這種情況下,是的,我相信我比優化器更好,在某些情況下,它正在對完全不相關的索引執行索引掃描。包括WITH INDEX修復了大多數優化器問題,我只是困惑它爲什麼沒有解決所有問題。 – 2010-12-21 16:28:24

+0

當我看到預算執行計劃運行緩慢時,它表示預計有92%的時間在做索引尋找我的強制指數。 – 2010-12-21 17:14:49

1

當自動統計功能開啓,引擎w烏爾德要更新的統計quite often,通常的方式往往比夜間:

Table Type | Empty Condition | Threshold When Empty |Threshold When Not Empty 
_________________________________________________________________________________ 
Permanent | < 500 rows  | # of Changes >= 500 | # of Changes >= 500 + (20% of Cardinality) 
___________________________________________________________________________ 
Temporary | < 6 rows  | # of Changes >= 6 | # of Changes >= 500 + (20% of Cardinality) 

但是,爲什麼不拿出猜測,只需部署計劃指南?見Understanding Plan Guides

+0

我從第一個鏈接使用「sp_autostats 」,以確保索引上的統計信息已打開。我還運行了「sp_dboption ,'auto create statistics','on',以確保它們實際上處於開啓狀態(即使這些框已被選中)。如果下週表現不佳,我會考慮制定一份計劃指南。 – 2010-12-21 17:09:52

+0

忽略汽車統計標誌沒有任何影響,所以我開始調查計劃指南。原來他們只適用於SQL 2005及更高版本,而不是2000.所以不要這樣做。 – 2011-01-05 14:36:01

相關問題