2016-08-11 85 views
1

我有一個表,my_table,列a,b,c, d,e我可以通過在其他索引中包含列來「鏈接」SQL Server中的非聚集索引嗎?

我有一個查詢過濾器上ab,並c並返回de;我有另一個查詢過濾bc,並返回de。如果我創建了以下指標:

CREATE NONCLUSTERED INDEX 
    ON my_table (a) 
    INCLUDE (b); 

CREATE NONCLUSTERED INDEX 
    ON my_table (b,c) 
    INCLUDE (d,e); 

第一個查詢(過濾上abc)可以同時使用索引?

SQL Server 2008 R2,如果它很重要。

+0

我不這麼認爲(並且我懷疑它會有效),SQL查詢分析器說什麼?是否包含(b,c)不是一個選項? – eckes

回答

0

是的,它叫做索引相交,https://www.brentozar.com/archive/2016/06/lets-make-match-index-intersection/

然而,爲了實現這一點,SQL Server必須確定每個索引查找都會削減表中匹配行的總數,但仍會導致返回多個行,但是兩次查找的交集又顯着減少表中匹配行的數量,而不是僅針對一個查找。

因爲我假設你真正的問題是如果你應該創建一個合理的性能來處理這個查詢的第三個索引,我的一般答案是否定的,你不應該。索引交集很可能是SQL Server在最壞情況下使用的一種可能性,即只針對一個索引進行查找時,不會顯着過濾足夠多的行以證明書籤查找的正確性。

有一種情況,第三個索引可能是有益的,當且僅當針對兩個當前索引的查找結果返回大部分錶行時,但兩個結果的交集非常小。對於SQL Server來說,從兩個分支中抽取多行並將行與行匹配可能比單個索引重一次以返回非常少的行要重得多。只有你能夠很好地瞭解你的數據,但看起來不太可能,並且很可能意味着你現有的兩個索引當前沒有足夠的選擇性,不足以用於索引查找。

0

通常沒有。

我聽說在極少數情況下,SQL Server的後續版本可以對一個操作使用多個索引,但是告訴我這個的人說他從未見過它實際發生過。

想想這樣,你會如何在C#中編寫代碼?

只使用第一個索引,您會找到您的行,然後在聚簇索引中爲缺失的數據執行散列表查找。

使用這兩個索引,您會在第一個索引中找到您的行,然後使用嵌套循環執行完整索引掃描。也就是說,對於來自索引的每個匹配記錄(out循環),您將遍歷第二個索引中的每個記錄以查找匹配(內部/嵌套循環)。

或者使用這兩個索引,你會發現第一個索引中的所有行和第二個索引中的所有行。然後,你將不得不弄清楚如何根據主鍵加入兩個列表,可能使用嵌套循環。

0

僅僅給出兩個查詢和它們查看的列,很難說出它將使用哪些索引。索引使用完全基於統計數據,並且執行計劃是圍繞這個建立的。即使你有一個索引,在一張足夠小的表上,你將得到索引掃描而不是尋找,因爲它不會節省時間或讀取來完成掃描。

要知道它將使用哪些指標,您需要知道a)表格有多大b)a,b,c單獨有多少c)基於b)的估計/實際執行計劃。這決定了你的索引使用。服務器將使用任何它認爲會以最快的速度獲得結果的計劃。

對於服務器生成執行計劃喬納森上述發生,它會採取一個相當具體的數據集。獨特的(或實際上唯一的)a,b,c使索引值得使用,一個深度和寬度很大的表,這將阻礙關鍵查找。當然,統計數據需要真實地表示執行計劃考慮使用兩個索引。

相關問題