2010-08-10 41 views
4

我有兩個索引視圖,v_Firstv_Second。當我有一個WHERE子句只基於其中一個視圖進行過濾時,這些視圖非常有用,但只要我有基於這兩個視圖的過濾條件,我就會得到兩個聚集索引掃描和較差的性能。爲什麼SQL服務器不使用我的索引? (過濾加入索引視圖)

我的查詢是:

SELECT * FROM dbo.v_First (NOEXPAND) 
JOIN dbo.v_Second (NOEXPAND) 
ON dbo.v_First.id = dbo.v_Second.id 
WHERE 
dbo.v_First.Firstname = 'JUSTIN' 
OR dbo.v_Second.Surname = 'JUSTIN' 

如果我註釋掉無論上述兩個WHERE條款中的一項然後我得到查詢和查詢執行,所以我知道我單獨定義了正確的索引。

爲什麼查詢在基於多個索引視圖進行篩選時無法執行,我該如何解決這個問題?

(對不起,我不能執行後的計劃,他們是平凡反正 - 聚簇索引上的兩個各自的觀點只有兩個聚集索引掃描和合並聯接)

更新:

v_First列:

  • ID(BIGINT,聚簇索引)
  • 姓(VARCHAR(254),nonclus tered指數)

v_Second列:

  • ID(BIGINT,聚簇索引)
  • 姓(VARCHAR(254),非聚簇索引)

所有索引的只包含單個列。

更新,第二:

我發現,如果OR條款變更爲AND子句,查詢執行罰款。我還發現,如果我更改查詢使用UNION語句而不是一個OR查詢執行罰款:

SELECT * FROM dbo.v_First (NOEXPAND) 
JOIN dbo.v_Second (NOEXPAND) 
ON dbo.v_First.ID = dbo.v_Second.ID 
WHERE dbo.v_First.Firstname = 'JUSTIN' 
UNION SELECT * FROM dbo.v_First (NOEXPAND) 
JOIN dbo.v_Second (NOEXPAND) 
ON dbo.v_First.ID = dbo.v_Second.ID 
WHERE dbo.v_Second.Surname = 'JUSTIN' 

據我所知這兩個查詢應該是等價的?

最後,我還發現,使用子查詢,而不是也有一個奇怪的效果,下面的查詢執行罰款:

SELECT * FROM dbo.v_First (NOEXPAND) 
-- JOIN dbo.v_Second (NOEXPAND) 
-- ON dbo.v_First.ID = dbo.v_Second.ID 
WHERE dbo.v_First.ID IN 
(
     SELECT ID FROM dbo.v_Second (NOEXPAND) 
     WHERE dbo.v_Second.Surname = 'JUSTIN' 
) 
OR dbo.v_First.Firstname = 'JUSTIN' 

但是,如果我去掉了JOIN(這樣我可以從列查詢結果中的第二個表),然後我在v_Second聚集索引上獲得表掃描(但請注意,它仍然比原始查詢更好,因爲它只涉及1次掃描,而不是2次)。

我很困惑 - 發生了什麼事?似乎我可以通過「重構」我的查詢來解決這些問題,但是我擔心我不明白這裏發生了什麼 - 我寧願避免進行我不完全理解的更改。

+0

@OMG - 幾乎只是創建索引視圖絕對必需的列和索引 - 我更新了我的問題。 – Justin 2010-08-10 02:04:38

+0

即使只有一個ID爲ID,名字,姓氏的表集中在ID上,並且分別在Firstname和Surname上編制索引,沿着查詢行的自連接也會導致類似的「錯誤」查詢計劃+執行速度緩慢。使用與第一個和相同索引相同的模式引入第二個表不會改進查詢。有趣。 – 2010-08-10 03:29:49

+0

一個問題:基表中有多少行? – gbn 2010-08-10 05:14:20

回答

3

觀察

  • 你有一個「OR」條件這是不優化搜索

  • 您可能需要ID添加到每個索引所以它的可用而不掃描/查找

  • 我無論如何,我都希望看到這些計劃。使用SET SHOWPLAN_TEXT

要回答你的問題,我想可能有與兩個文本列基表中的一個指數,讓它掃描這一點。 OR沒有給你很多選擇,2索引視圖是毫無意義的恕我直言。在更新之後,你有一些人爲的SQL構造:你真的需要2個索引視圖和一個花哨的派生表或UNION嗎?

+0

索引視圖是爲了解決基表的一些侷限性 - 它非常奇怪並且不夠理想 - 我正在研究將索引視圖看作是一種二惡意的方法。 – Justin 2010-08-10 05:45:24