2013-01-16 68 views
2

我有一個包含主鍵和兩個外鍵的表,其中都允許NULLS。OR子句中存在的索引列

當我爲每兩列分別創建索引時,查詢運行約2-3秒並返回約300000行。

當我爲這兩列創建複合非聚簇索引時,對於相同行數的查詢運行大約10分鐘。

重要的是要注意到,兩列出現在WHERE條件是重要的,使用OR子句的工作方式,是這樣的:在其中執行查詢

Select 
    SomeColumn 
From 
    SomeTable 
Where 
    FirstColumn = x OR SecondColumn = x 

平臺是SQL 2008 R2。

爲什麼在這兩種情況下執行時間有這樣的差異?

+0

聚集索引不是合成的,它包含一個列,它是表的標識列,因此是主鍵。其他兩列分別創建兩個索引,或者分別創建一個組合索引,並且這兩列是WHERE過濾器中的那些列。 – veljasije

+0

向我們展示了執行計劃,我的猜測是其中一個非聚集索引從未被使用,並且在複合索引中,您選擇了錯誤的列作爲第一個列,合成索引中第一列的數據選擇性是多少 - argh,sry for混亂。無法編輯它 – WKordos

回答

2

如果您有兩個單獨的索引,並且WHERE子句中只有那兩列,那麼優化程序可以有效地使用它們來確定所需的行(假定爲INDEX SEEK)。

複合索引不是很好,因爲複合索引首先在第一個索引列上排序,然後是第二個索引列,依此類推。所以它就像你的OR條件中的第一列一樣有用。要確定第二列的行,優化器必須掃描整個表,因爲它沒有合適的索引。

如果你有這個場景的大表,那麼對於簡單的查詢,單個索引通常會比你所問的要快。它實際上也取決於所選列,查詢複雜度,覆蓋索引等。

我自己也有這個問題。請參閱:Query performance of combined index vs. multiple single indexes vs. fulltext index以供參考。

1

的一點是,在索引中的列的順序關係

create table #temp (col1 int, col2 int) 
create nonclustered index index1 on #temp(col1, col2) 

是不一樣的

create nonclustered index index2 on #temp(col2, col1) 

在評論,在查詢執行後的計劃

或更改列在複合索引中的順序並重新運行查詢

如評論中所述,我的g UESS是,當有兩個非聚集索引 - optymizer使用它們 之一,如果你把它們並重新創建爲具有低數據選擇性第一列的索引不會被使用,並且查詢執行時間指數將遭受

如果您發佈查詢,將會容易得多