2010-05-27 52 views
3

我有以下查詢:簡單查詢幫助 - 爲什麼不是索引被使用?

SELECT MAX([LastModifiedTime]) FROM Workflow 

有大約在工作流程表400M行。 LastModifiedTime列上的索引如下:

CREATE NONCLUSTERED INDEX [IX_Workflow_LastModifiedTime] ON [dbo].[Workflow] 
(
[LastModifiedTime] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) 

上述查詢需要1.5分鐘執行。爲什麼SQL Server不使用上述索引並簡單地檢索索引中的最後一行以獲取最大值?

順便說一下,該查詢的查詢計劃顯示index scan正在完成上述索引。

謝謝。

+0

你可以嘗試做一個'UPDATE STATISTICS dbo.Workflow'或'UPDATE STATISTICS dbo.Workflow IX_Workflow_LastModifiedTime',看看是否有什麼差別? – 2010-05-27 18:59:54

+0

@marc_s - 它使用索引,但它正在掃描它。爲什麼它不會落到最後一行呢?這將是最大的價值。除非需要1:30才能在索引中有400M行時下降到最後一行? – 2010-05-27 19:07:04

+0

是的,也許如果你更新的統計數據,查詢優化器會發現有太多的行只是掃描 - 並找到一些其他的策略來得到所需的結果.... – 2010-05-27 20:26:06

回答

3

神祕的查詢優化的方式...

如果有可能,我建議你改變這樣的查詢:

SELECT TOP (1) [LastModifiedTime] 
FROM Workflow 
ORDER BY [LastModifiedTime] DESC; 

這是語義相同和優化器將不再考慮使用MAX聚合和掃描(顯然它現在正確)。它可能會考慮在工作臺上做一個SORT,但希望這樣一個計劃的估計成本將遠大於逆向尋求的成本。

至於爲什麼優化器選擇顯然是一個明顯不好的計劃,通常涉及很多因素,很難從SO帖子診斷。一般來說,擁有ASC索引並不總是替代缺少DESC索引,而且您的特定列統計信息(分發信息)可能已經在查詢優化程序內達到了某個臨界點,因此它決定選擇scan + aggregate而不是反向掃描+頂部。

0

你可以從執行計劃中知道它是否使用索引?如果不是,最後一次分析表/索引的時間是?如果它從來沒有被分析過,也許SQL服務器仍然認爲它只有100行,並且執行表掃描會更快。

+0

本專欄的索引僅在兩小時前添加。他們的查詢計劃顯示索引掃描正在索引上完成。 – 2010-05-27 18:54:08

+3

@Randy Jut出於好奇,這個查詢需要多長時間:'SELECT TOP 1 LastModifiedTime FROM WorkFlow ORDER BY LastModifiedTime DESC' – 2010-05-27 19:06:53

+0

沒有真正的區別。索引掃描仍在進行中。 – 2010-05-27 19:25:55

1

我有一個類似日期時間字段(假設是你的數據類型)和4M行的表 - 你的1%,但同樣的查詢幾乎只要我點擊'執行'就回來了。我的指數幾乎和你的一樣:

CREATE NONCLUSTERED INDEX [IX_PartViewTrack_SearchDate] ON [dbo].[PartViewTrack] 

(
[SearchDate] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,  
IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, 
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

的執行計劃顯示索引掃描。

只是咧嘴笑 - 下降的指數,看看需要多長時間?

0
SELECT MAX([LastModifiedTime]) FROM Workflow with(nolock) 

這是否更快?

+0

它可能稍微快一些,但真正的問題是它正在執行索引掃描而不是查找。添加(nolock)不會改變這一點。 – 2010-05-27 19:24:40

0

一個黑白問題,沒有(對我)一個明顯的答案。這裏有一些非常愚蠢的想法,只是爲了清除空氣。

  • 這是表嗎?如果一個視圖,底層 結構可能會阻礙。 (I 忘記了,您可以在物化視圖上創建非集羣 索引嗎?)

  • 是否存在爭用?如果其他用戶 在 表上有長期鎖定,則可能會降低它的速度。 此外,極其頻繁的更新 可能會拋出。

  • 查詢計劃顯示索引掃描 正在運行。索引是否參考 這個索引? (還有其他的指標?一個聚集索引? 可能不是一個問題,而是觀念摸索 這裏。)

  • 你使用模式?索引是 dbo.Workflow,但查詢不包含 指定「dbo」。 (就像我說的, 摸索的想法在這裏。)

所有這些聽起來很蹩腳的,但沒有動手訪問這些類型的問題可能是非常艱難弄清楚。

0

這是一個很長的畫面:我發現Oracle有時需要一個字段在它將使用索引之前不允許空值。 SQL Server中是否有類似的限制?

0

分析索引首先使用命令

DBCC SHOW_STATISTICS (table_name, index_name) 

檢查,如果你的指數是覆蓋整個表。如果沒有,請嘗試更新的統計數據使用

UPDATE STATISTICS table_name