我有一個視圖,這是一個連接的集合。爲了這個問題的目的,我將簡化如下的觀點。注意,Table1.Table1ID
是主鍵,Table2.Table1ID
是外鍵。SQL Server視圖執行計劃:是否與UNION相同?
CREATE VIEW [View1] AS
SELECT t1.Column1, t2.Column2
FROM Table1 t1
JOIN Table2 t2 ON t1.Table1ID = t2.Table1ID
使用用於此目的的觀點是好的,因爲它減少了加入我在我的代碼做的數量,並允許SQL Server更有效地優化了連接。例如:
SELECT Column1, Column2
FROM View1
WHERE Column1 = 'abc'
AND Column2 = 'xyz'
GROUP BY Column1, Column2
SQL服務器通過接合只從表1記錄,其中在列1的值是「ABC」和來自表2的記錄的子集,其中在列2的值是「XYZ」的子集優化上述查詢。換句話說,在應用連接之前,SQL Server執行計劃巧妙地將過濾應用於視圖中的相應表,從而減少了需要在連接中記錄的記錄數。
但是,如果我通過改變WHERE
子句中AND
運營商的運營商OR
改變前查詢,執行計劃確實不執行聯接之前應用的篩選。
SELECT Column1, Column2
FROM View1
WHERE Column1 = 'abc'
OR Column2 = 'xyz'
GROUP BY Column1, Column2
上述查詢的執行計劃首先連接來自Table1和Table2的所有記錄,然後應用where子句秒。這符合布爾邏輯,因爲在連接表並且列1和列2中的值存在並佔據之前,不能滿足OR
運算符測試。
另一方面,以下查詢返回與前一個查詢相同的結果集。
SELECT Column1, Column2
FROM View1
WHERE Column1 = 'abc'
UNION
SELECT Column1, Column2
FROM View1
WHERE Column2 = 'xyz'
後者兩個查詢產生相同的結果,但兩者中的第二個由SQL Server,使得執行計劃應用where子句的各表中的各SELECT
語句聯接是spplied之前優化在視圖中,導致加入的記錄更少。這將導致更高效的查詢,即使視圖實際上被調用了兩次,並且結果記錄集的交集被UNION
返回。
我的問題是:
- 爲什麼不SQL Server的優化使用類似於過去的查詢執行計劃的倒數第二個查詢?
- 有沒有辦法定義視圖,以便SQL Server使用類似於最後一個查詢的執行計劃來優化它?
謝謝。
最後的查詢是*不*相等 - 因爲'UNION'消除重複 - 我猜測你在測試數據中沒有重複*,但這不是一個普遍安全的假設。 – 2012-03-29 07:00:06
@Damien_The_Unbeliever:好的。我離開了關鍵部分。 'GROUP BY'。 – Kuyenda 2012-03-29 16:44:20