2013-02-08 98 views
6

考慮以下三個查詢:爲什麼在SELECT子句中使用非索引字段時性能下降?

select sampleno from sample 
    where markupdate > '1/1/2010' 

select sampleno, markupdate from sample 
    where markupdate > '1/1/2010' 

select sampleno, markuptime from sample 
    where markupdate > '1/1/2010' 

samplenomarkupdate被索引字段(sampleno是主鍵)

markuptime不是索引

查詢1和2需要約1秒到運行(返回237K行)。 3分鐘後,查詢3仍在運行。

爲什麼在SELECT子句中包含非索引字段會導致性能下降?

這是一個SQL 6.5數據庫。

回答

5

表格的數據(基本上是所有列)都存儲​​在聚簇索引中。聚簇索引是一種二叉樹,允許在索引列上進行二分搜索。它是特殊的(聚集),因爲它包含葉級別的所有其他列。通常,聚集索引也是主鍵。根據你的情況,它是:

(sampleno) include (markupdate, markuptime, ...) 

一個非聚集索引包含索引列(S)和(葉級)的聚集索引。在使用非聚簇索引時,數據庫必須查找聚簇索引中的所有其他列。該過程稱爲查找。在你的情況下,(markupdate)非聚集索引:

(markupdate) include (sampleno) 

該指數包含了所有的數據上markupdate, sampleno查詢。這種指數的技術術語是,涵蓋索引。但是,當您向查詢添加markuptime時,索引不再覆蓋。它必須在聚簇索引中查找markuptime的值。查找是廣泛的。

只有你的第三個查詢需要查找。這就是爲什麼你的第三個查詢比較慢。

+0

有什麼我可以做的查詢臨時包括markuptime在索引或必須創建包含markuptime表的索引? – blueshift 2013-02-08 17:04:04

+1

您可以添加INCLUDE以在MarkUpdate的非聚集索引中包含MarkupTime,這將爲您提供第三個查詢的「覆蓋索引」。 (Nevermind,如果你有更新版本的SQL,你可以這樣做......我想只需在MarkUpdate索引中添加MarkupTime作爲另一列。) – 2013-02-08 17:04:52

相關問題