我發現了一個非常奇怪的行爲,我必須解釋。我們有一個簡單的表格,大約有450.000個條目(MSSQL 2008 R2)。MSSQL:爲什麼這個索引比其他索引快10倍?
此表的索引是很簡單的:
指數#1包含:
[OwnerUserID] -> int, 4 byte
[TargetQuestionID] -> int, 4 byte
[LastChange] -> date, 8 byte
指數#2包含:
[LastChange] is a date, 8 byte
[OwnerUserID] is an int, 4 byte
[TargetQuestionID] is an int, 4 byte
正如你所看到的,所不同的只是列的順序略有不同;在這兩個指標中,葉子的大小相同,16個字節(遠離我見過做的非常大的數據庫,一些DBA的)
的查詢很簡單:
Query #1:
- Asks just for the last entried element (top(1)) ordered by LastChange, so it takes only LastChange into account
Query #2:
- Asks just for the last entried element (top(1)) entried for a distinct OwnerUserID, so it takes OwnerUserID and LastChange into account
結果是:
指數#1查詢#1超級慢,雖然我認爲這應該是OK,因爲數據葉子是真的不大(16個字節)
指數#2是用於查詢#2超慢(但由於它需要考慮兩個值,OwnerUserID + LastChange = 8個字節,我沒有看到任何爲什麼它應該更慢/更快)
我們的想法是隻有一個索引,但由於每個查詢方案的性能相差10-11倍,我們最終並行創建了這兩個索引的兩個,我們認爲我們可以選擇其中一個 - 因爲這個指數並不是那麼大/複雜,你會認爲這個列順序上的細微差別會受到傷害。
所以,現在我們是在浪費一倍的空間,因爲該表由每天1萬行左右的增長,我們將磁盤空間問題的地方在未來...
起初,我以爲這是因爲一些內部NHibernate的問題,但我們檢查了性能監視器,結果是絕對可重現的。
好像與指標MSSQL性能高度依賴的datetime-列的使用,因爲這個簡單的例子表明,這可能崩潰全性能: -/
檢查執行計劃。 –
嘿嘿,那是真的 - 我們只檢查了SQL分析器,看看它需要多長時間,但不是執行計劃: -/ – johngrinder