2010-02-05 104 views
4

我正在使用SQL 2000,並且在包含大約3000萬行的表上運行簡單的select語句。選擇查詢如下所示:優化選擇查詢

select col1, col2, col3 from Table1 where [email protected] and [email protected] and [email protected] 

表中有一個聚集索引(即主鍵),但沒有用作where條件。上面提到的所有標準都沒有索引。

如何優化此查詢?

如果我在where子句中爲每列添加索引,那會有什麼區別嗎?

如果我在where子句中有10個列,那麼這10個列中的所有列都有索引嗎?

編輯:這可能是最常見的面試問題之一:)

回答

5

是的,它會產生巨大的差異。

您應該添加一個包含三個字段的索引,而不是爲每個字段添加一個索引。 (當然這在實踐中的使用取決於字段的獨特性以及您將在桌面上使用的其他查詢)。

請注意,添加索引時,插入或刪除時也會產生很小的負面影響記錄到表中或更新記錄的索引字段。

+0

指數功效神奇!謝謝....但只是好奇,有沒有其他方法可以用來更快地做出這樣的查詢? – Bhaskar 2010-02-05 12:44:55

+0

@Bhaskar:是的,你可以走得更遠。分析執行計劃,看看最需要的是什麼。最有效的索引取決於表中包含的數據以及它的變化量。如果表中有許多插入/更新/刪除操作,則應檢查索引的碎片並在索引趨向於碎片時指定填充因子。 – Guffa 2010-02-05 13:00:57

2

如果我添加索引中 每列的where子句中,這會讓任何 區別?

是的,添加索引會產生巨大的性能差異。這是以索引佔用大量磁盤空間爲代價的,並且對INSERT和UPDATE命令的影響非常小。

如果我有where子句中10列, 都應該在這10列在他們 指數?

情況並非總是如此。如果我們以您提供的SQL查詢爲例,並且僅在col4上創建索引,那麼select * from Table1 where [email protected]可能只返回幾條記錄。在這種情況下,由於數據庫引擎只需掃描返回的那幾條記錄,就不會在col5和col6上獲得太多索引。

因此,正如您所看到的,這取決於您正在存儲的數據類型。另外,對於任何基數較低的列(即只有少量唯一值的列),索引也可能沒有多大用處。

2

來自標準的哪一列最具選擇性?在該列上創建索引最會影響性能。 如果您將另一列添加到相同的索引或不是,取決於選擇性。您需要檢查查詢計劃以找出該問題:)

4

如何優化此查詢?

您可以覆蓋索引:

CREATE INDEX ix_table1_456__123 ON table1 (col4, col5, col6) INCLUDE (col1, col2, col3) 

,查詢甚至不會做一個表查找。

如果我在where子句中爲每列添加索引,那會有什麼區別嗎?

與沒有索引相比,這將最有可能改善查詢,但創建包含覆蓋的組合索引最可能會更好。但是,如果每個列的基數都很高(即它是UNIQUE或接近它),那麼與組合索引相比,創建單個索引甚至可以提高查詢的質量。

如果某些列的大小很大(例如VARCHAR(400)),而另一個小列的基數較高,則尤其如此。

如果我在where子句中有10列,那麼這10列中的所有列都有索引嗎?

如果你有10列,還有的,正如我上面所說,並增加了密鑰大小之間的權衡(這會降低性能),增加選擇性。

如果比方說第一個3列是唯一的或幾乎唯一的,那麼添加附加列不會增加選擇性,但會增加密鑰大小。

該索引將會變得更大,這將需要額外的時間來搜索它。

如果3列提供足夠高的選擇性,則不應在所有10列上創建索引,因爲遍歷較大的索引將比讀取一些額外的鍵更昂貴。

您可能需要閱讀這篇文章在我的博客:

+0

索引像魔術一樣工作!謝謝....但只是好奇,有沒有其他方法可以用來更快地做出這樣的查詢? – Bhaskar 2010-02-05 12:45:29