簡體   English   中英

SQL Server如何處理視圖后面的表上的索引?

[英]How does SQL Server treat indexes on a table behind a view?

所以我試圖了解SQL Server如何在視圖后面的表上使用索引。 下面是場景:表A在字段1和2上具有復合聚簇索引,在字段3和4上具有非聚簇索引。

視圖A針對表A編寫以過濾掉其他字段,但字段1-4是視圖的一部分。 因此,我們編寫一個查詢,將視圖連接到非聚簇索引字段上的另一個表。

生成的查詢計划使用聚簇索引掃描(而不是預期的非聚簇索引搜索)命中表A. 但是,如果我們用表替換FROM子句中的視圖,則查詢計划會訪問非聚簇索引,並獲得我們預期的索引搜索。

SQL引擎是否應該使用構建視圖的表上的索引? 既然沒有,為什么不呢?

當您考慮非物化視圖和優化時 - 想象它們是這樣的:

引擎將視圖文本“剪切並粘貼”到您執行的每個查詢中。

好吧,這不是100%真實,但它可能是最有用的方式來考慮性能方面的預期。

但是,觀點可能很棘手。 人們傾向於認為僅僅因為列在視圖中,這意味着在查詢性能方面有重要意義。 事實是,如果使用您的視圖的查詢不包含一組列,則可以“優化掉”。 因此,如果您要在視圖中從基表中選擇每一列,然后在實際使用視圖時只選擇一列或兩列,則只考慮您選擇的那兩列,將優化查詢。

這樣做的另一個后果是您可以使用視圖來非常積極地平整表結構。 所以,比方說,我有以下架構:

Widget
-------
ID (UNIQUE)
Name
Price
WidgetTypeID (FK to WidgetType.ID)

WidgetType
----------
ID (UNIQUE)
Name

vw_Widgets
----------
SELECT w.ID, w.Name, w.Price, w.WidgetTypeID, wt.Name AS TypeName
FROM Widgets w
LEFT JOIN WidgetType wt
   ON wt.ID = w.WidgetTypeID;

請注意視圖定義中的LEFT JOIN。 如果您只是簡單地SELECT Name, Price FROM vw_Widgets ,您會注意到WidgetType甚至沒有參與查詢計划! 它完全被優化了! 這適用於跨唯一列的LEFT JOINS,因為優化器知道由於WidgetType的ID是UNIQUE,因此它不會從連接生成任何重復的行。 由於存在FK,您知道可以將連接保留為LEFT連接,因為您將始終擁有相應的行。

因此,帶有觀點的故事的寓意是,您在一天結束時選擇的列是重要的列,而不是視圖中的列。 視圖在創建時不會進行優化 - 它們在使用時會進行優化。

你的問題不是關於觀點

你的問題實際上更通用 - 為什么你不能使用NC索引? 我無法告訴你真的因為我看不到你的架構或你的具體查詢,但足以說明在某個時刻,優化器會發現查找其他字段的成本超過了它的成本。掃描表(因為搜索是昂貴的)並忽略您的非聚集索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM