摘要
本文檔介紹 SQL Server
企業版的新功能
索引視圖
講解索引視圖並討論一些提高性能的具體方案
什麼是索引視圖?
許多年來
Microsoft® SQL Server
; 一直都提供創建虛擬表(稱為視圖)的功能
在過去
這些視圖主要有兩種用途
提供安全機制
將用戶限制在一個或多個基表中的數據的某個子集
提供一種機制
允許開發人員定制用戶如何才能以邏輯方式查看存儲在基表中的數據
SQL Server
已經擴展了 SQL Server 視圖的功能
以提高系統性能
它可以在一個視圖上創建唯一的群集索引和非群集索引
可以改進最復雜查詢的數據訪問性能
在 SQL Server
中
擁有唯一群集索引的視圖被稱為索引視圖
注意
索引視圖只是 SQL Server
企業版和 SQL Server
開發人員版的一個功能
從數據庫管理系統 (DBMS) 的觀點來看
視圖是數據(元數據)的說明
創建典型視圖時
通過 SELECT 語句(定義一個顯示為虛擬表的結果集)來定義元數據
當其它查詢的 FROM 子句中引用了某個視圖時
將從系統目錄中檢索該元數據
並對其進行擴展以代替該視圖的引用
在視圖擴展之後
查詢優化器會為正在執行的查詢編譯單個執行計劃
如果是非索引視圖
視圖在運行時將被實體化
任何計算(如聯接或聚合)都在為每個引用該視圖的查詢執行查詢期間進行
(視圖並不總需要被完全實體化
查詢可以包含其它一些謂詞
聯接或聚合
以應用於該視圖所引用的表和視圖
)在視圖上創建了唯一的群集索引之後
視圖的結果集會立即被實體化並持續保存在數據庫的物理存儲空間中
以便節省這種操作所占用的大量資源
在執行查詢時
有兩種方法可以使用索引視圖
查詢可直接引用索引視圖
更重要的是
如果查詢優化器確定視圖能夠替換為查詢的部分或全部
而且這是低成本的查詢計劃
則可以選擇索引視圖
第二種情況是使用索引視圖代替基礎表及其普通索引
此時
不需要在查詢中引用視圖
查詢優化器即可在執行查詢期間使用該視圖
這樣
現有的應用程序無需更改即可從新建的索引視圖中獲益
通過索引視圖提高的性能
使用索引來提高查詢性能並不是什麼新觀念
不過
索引視圖還具有使用標准索引不能獲得的其它性能優點
索引視圖能夠在以下方面提高查詢性能
能夠預先計算聚合並將其存儲在索引中
從而最大限度地減少在執行查詢期間進行成本很高的計算
能夠預先聯接表並存儲生成的數據集
能夠存儲聯接或聚合的組合
下圖說明了查詢優化器使用索引視圖時一般能夠提高多少性能
提供的查詢復雜程度各不相同(例如
聚合計算的數量
所用表的數量或謂詞數)
並包括來自實際生產環境的數百萬行的大表
圖
當查詢優化器使用索引視圖時一般能夠提高多少性能
使用視圖的輔助索引
視圖的輔助性非群集索引可以提高其它查詢性能
與表的輔助索引類似
視圖的輔助索引也可以提供更多選項
以便查詢優化器在編譯過程中從中進行選擇
例如
如果查詢包括群集索引未涉及的列
優化器可以在計劃中選擇一個或多個輔助索引
從而避免對索引視圖或基表進行費時的全局掃描
由於索引需要不斷維護
所以為架構添加索引會增加數據庫的額外開銷
因此應該認真考慮
找到索引和維護額外開銷之間的平衡點
使用索引視圖的好處
實現索引視圖之前
請先分析數據庫的工作量
運用自己對查詢以及各種工具(例如 SQL 分析器)的知識來鑒別使用索引視圖可以獲益的查詢
如果經常進行聚合和聯接
最好使用索引視圖
並非所有查詢都會從索引視圖中獲益
與普通索引類似
如果未使用索引視圖
就沒有好處可言
在此情況下
不但不能提高性能
還會加大磁盤空間的占用
增加維護和優化的成本
但是
如果使用了索引視圖
它們可以(成數量級地)明顯地提高數據訪問的性能
這是因為查詢優化器使用存儲在索引視圖中的預先計算的結果
從而大大降低了執行查詢的成本
查詢優化器只在查詢的成本比較大時才考慮使用索引視圖
這樣可以避免在查詢優化成本超出因使用索引視圖而節省的成本時
試圖使用各種索引視圖
當查詢成本低於
時
幾乎不使用索引視圖
使用索引視圖可以受益的應用包括
決定支持工作量
數據集市
聯機分析處理 (OLAP) 庫和源
數據挖掘工作量
從查詢的類型和模式的角度來看
受益的應用可被歸納為包含以下內容的應用
大表的聯接和聚合
查詢的重復模式
重復聚合相同或重疊的列集
針對相同關鍵字重復聯接相同的表
上述的組合
相反
包含許多寫入的聯機事務處理 (OLTP) 系統或更新頻繁的數據庫
可能會因為要同時更新視圖和根本基表而使維護成本增加
所以不能利用索引視圖
查詢優化器如何使用索引視圖
SQL Server 查詢優化器可自動確定何時可以將索引視圖用於給定的查詢執行中
查詢中無需直接引用視圖
優化器就可以將該視圖用於查詢執行計劃
因此
無需對現有的應用程序本身進行任何更改
這些應用程序即可利用索引視圖
唯一需要做的就是創建索引視圖
優化器的考慮因素
查詢優化器會考慮幾個條件來確定索引視圖能涵蓋部分查詢還是整個查詢
這些條件符合查詢中的單個 FROM 子句並包含以下內容
查詢 FROM 子句中的表必須是索引視圖 FROM 子句中的表的超集
查詢中的聯接條件必須是視圖中聯接條件的超集
查詢中的聚合列必須是視圖中的聚合列的子集
查詢選擇列表中的所有表達式都必須源自於視圖選擇列表或源自於不包括在視圖定義中的表
查詢搜索條件謂詞必須是視圖定義中搜索條件謂詞的超集
視圖搜索謂詞中的每個合取項都必須以同樣的形式出現在查詢搜索謂詞中
查詢搜索條件謂詞中的所有列(屬於視圖定義中的表)都必須出現在下列一項或多項中
視圖定義中的同一個謂詞
GROUP BY 列表
視圖選擇列表(若沒有 GROUP BY 列表)
如果查詢包含多個 FROM 子句(子查詢
派生表
UNION)
優化器可以選擇多個索引視圖來管理含有多個 FROM 子句的查詢
注意
也存在例外情形
即優化器可能將兩個 FROM 子句折疊成一個(將子查詢折疊成聯接或將派生表折疊成聯接變體)
如果出現此類情況
索引視圖替換可能會涵蓋原查詢中的多個 FROM 子句
本文檔結尾介紹了演示這些條件的查詢示例
而建議的最佳方法就是
讓查詢優化器來確定在查詢執行計劃中使用哪些索引(如果有的話)
使用 NOEXPAND 選項
NOEXPAND 選項強制查詢優化器象對待包含群集索引的普通表一樣對待視圖
在此情況下
必須在 FROM 子句中直接引用索引視圖
例如
SELECT Column
Column
FROM Table
View
WITH (NOEXPAND)WHERE
使用 EXPAND VIEWS 選項
另外
用戶可以在查詢結束時通過使用 EXPAND VIEWS 選項
明確地將索引視圖排除在考慮之外
例如
SELECT Column
Column
FROM Table
View
WHERE
OPTION (EXPAND VIEWS)
如果使用該選項
查詢優化器在評估低成本的方法(該方法涉及查詢中引用的列)時將忽略所有視圖索引
設計的考慮因素
為數據庫系統找到適當的索引集是相當復雜的
盡管在設計普通索引時要考慮許多可能性
但將索引視圖添加到架構會極大地增加設計和潛在結果的復雜性
例如
索引視圖可用於
查詢中所引用表的任何子集
查詢中條件的任何子集(屬於表的上述子集)
分組列
聚合函數
如 SUM
應同時設計表的索引和索引視圖
以便從各個結構中獲得最佳結果
由於索引和索引視圖都可能對給定的查詢有用
所以單獨設計它們會導致多余的建議方案
以致存儲和維護開銷較高
在調整數據庫的物理設計時
必須均衡考慮各種查詢集的性能要求與數據庫系統必須支持的更新操作
因此
為索引視圖找到一種合理的物理設計是一項很具挑戰性的任務
因而應該盡可能地使用
索引微調向導
如果存在許多索引視圖可供查詢優化器考慮用於特定查詢
查詢優化成本會顯著增加
查詢優化器可能考慮為查詢中表的任意子集定義的所有索引視圖
拒絕每一個視圖之前
必須對它進行語法分析
然後研究其是否可能成為潛在的替換體
這可能需要一些時間
尤其是在有數百個此類的視圖用於給定的查詢時
視圖必須符合幾項要求
您才能為其創建唯一的群集索引
在設計階段
請考慮以下要求
視圖以及視圖中引用的所有表都必須在同一數據庫中
並具有同一個所有者
索引視圖無需包含要供優化器使用的查詢中引用的所有表
必須先為視圖創建唯一群集索引
然後才可以創建其它索引
創建基表
視圖和索引以及修改基表和視圖中的數據時
必須正確設置某些 SET 選項(在本文檔的後文中討論)
另外
如果這些 SET 選項正確
查詢優化器將不考慮索引視圖
視圖必須使用架構綁定創建
視圖中引用的任何用戶定義的函數必須使用 SCHEMABINDING 選項創建
另外
還要求有一定的磁盤空間來存放由索引視圖定義的數據
設計准則
From:http://tw.wingwit.com/Article/program/SQLServer/201311/22051.html