Sql-Server
查看列消除
當您只需要選擇特定的列時,我對查詢優化器如何從視圖的查詢中消除不必要的列感到有些困惑。
這是我的看法:
CREATE VIEW Schema1.Object1 AS SELECT Object2.Column1 AS Column2, Object2.Column3 AS Column4, Object3.Column5, Object3.Column6, Object4.Column1 AS Column7, Object5.Column1 AS Column8, Object5.Column9 AS Column10, Object5.Column11 AS Column12, Object5.Column13 AS Column14, Object5.Column15 AS Column16, Object5.Column17 AS Column18, Object5.Column19 AS Column20, Object5.Column21 AS Column22, Object5.Column23 AS Column24, CASE WHEN Object2.Column25 >= Object5.Column25 THEN Object2.Column25 ELSE Object5.Column25 END AS Column25, Object2.Column26 FROM Schema1.Object6 AS Object2 CROSS JOIN Schema2.Object7 AS Object4 JOIN Schema1.Object8 AS Object3 ON Object3.Column5 = Object2.Column5 AND Object3.Column7 = Object4.Column1 LEFT JOIN Schema1.Object9 AS Object5 ON Object5.Column4 = Object2.Column3 JOIN Schema3.Object10 AS Object11 ON Object5.Column26 = Object11.Column27
現在,我只想進行如下查詢:
SELECT Column2 FROM Schema1.Object1
…但是估計的計劃包括視圖中的所有列,即使查詢沒有返回它們。
為什麼會這樣?我可以避免這種情況嗎?
這是查詢計劃的連結:https ://1drv.ms/u/s!AhdjYi359YDTgYF6sLo8fBsj5H6Ilg
計劃中的每個節點僅投影正確滿足查詢所需的最低限度的列。您可以通過查看每個運算符的輸出列表來了解這一點。例如,最終連接僅列出一列。SQL Server 非常擅長刪除不需要的投影。
我想也許您期望消除一個或多個**聯接。**這更棘手,因為優化器必須小心不要改變查詢的含義。正如 Rob Farley在 SQL Server中的 JOIN 簡化中所描述的,有四個原因可以保持連接:
- 額外的列。需要連接來提供查詢所需的列,因為該列出現在最終結果中,或者某些中間步驟(如過濾或不同的連接)需要它。
- 行重複。連接可以增加匹配的行數。例如,表 A 中的單行可能與表 B 中的兩行連接,因此結果將包含表 A 行中資訊的兩個副本。
- 行消除。內連接可以消除表 A 中不與表 B 中的任何行連接的行。
- 添加了 NULL。右連接或完全連接可以引入新的 NULL,其中表 A 中的行與表 B 中的行不匹配。
SQL Server 在刪除不必要的連接方面做得很好(雖然不是完美的),但這樣做是安全的。僅當優化器保證上述四種連接效果都不會影響結果時,才能刪除連接。
在您的情況下,上述第 2 項和第 3 項很可能適用。您可以通過使用左連接而不是內連接來使視圖更簡化,並且可能
DISTINCT
在您的外部查詢中添加一個。有關範例,請參見 Rob 的文章。