我有兩個索引視圖,v_First
和v_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次)。
我很困惑 - 發生了什麼事?似乎我可以通過「重構」我的查詢來解決這些問題,但是我擔心我不明白這裏發生了什麼 - 我寧願避免進行我不完全理解的更改。
@OMG - 幾乎只是創建索引視圖絕對必需的列和索引 - 我更新了我的問題。 – Justin 2010-08-10 02:04:38
即使只有一個ID爲ID,名字,姓氏的表集中在ID上,並且分別在Firstname和Surname上編制索引,沿着查詢行的自連接也會導致類似的「錯誤」查詢計劃+執行速度緩慢。使用與第一個和相同索引相同的模式引入第二個表不會改進查詢。有趣。 – 2010-08-10 03:29:49
一個問題:基表中有多少行? – gbn 2010-08-10 05:14:20