在本教學中,將學習如何創建一個SQL Server索引視圖,該視圖在資料庫中物理存儲數據。
SQL Server索引視圖簡介
常規SQL Server視圖是保存的查詢,它們提供一些好處,例如查詢簡單性,業務邏輯一致性和安全性。 但是,它們不會提高基礎查詢性能。
與常規視圖不同,索引視圖是物理化視圖,它們在物理上像表一樣存儲數據,因此如果使用得當,可能會提供一些性能優勢。
要創建索引視圖,請使用以下步驟:
- 首先,創建一個使用
WITH SCHEMABINDING
選項的視圖,此選項將視圖綁定到基礎表的模式。 - 其次,在視圖上創建唯一的聚簇索引,它實現了視圖。
由於WITH SCHEMABINDING
選項,如果要更改影響索引視圖定義的基礎表的結構,則必須先刪除索引視圖,然後再應用更改。
此外,SQL Server要求索引視圖中的所有對象引用都包含兩部分命名約定,即schema.object
,並且所有引用的對象都在同一個數據庫中。
當基礎表的數據發生更改時,索引視圖中的數據也會自動更新。 這會導致引用表的寫入開銷。 當寫入基礎表時,SQL Server也必須寫入視圖的索引。 因此,應該只針對具有頻繁數據更新的表創建索引視圖。
創建SQL Server索引視圖示例
以下語句基於示例資料庫中的production.products
,production.brands
和production.categories
表的列創建索引視圖:
參考以下語法,創建一個索引視圖:
CREATE VIEW product_master
WITH SCHEMABINDING
AS
SELECT
product_id,
product_name,
model_year,
list_price,
brand_name,
category_name
FROM
production.products p
INNER JOIN production.brands b
ON b.brand_id = p.brand_id
INNER JOIN production.categories c
ON c.category_id = p.category_id;
注意:視圖名稱後使用
WITH SCHEMABINDING
選項,其餘部分與常規視圖相同。
在為視圖創建唯一的聚簇索引之前,通過查詢常規視圖中的數據並使用SET STATISTICS IO
命令來檢查查詢I/O開銷統計資訊:
SET STATISTICS IO ON
GO
SELECT
*
FROM
production.product_master
ORDER BY
product_name;
GO
SQL Server返回以下查詢I/O成本統計資訊:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'products'. Scan count 1, logical reads 5, physical reads 1, read-ahead reads 3, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'categories'. Scan count 1, logical reads 2, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'brands'. Scan count 1, logical reads 2, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
從輸出中可以清楚地看到,SQL Server必須在返回結果集之前從三個相應的表中讀取。
現在,為視圖添加一個唯一的聚簇索引:
CREATE UNIQUE CLUSTERED INDEX
ucidx_product_id
ON production.product_master(product_id);
此語句實現了視圖,使其在資料庫中具有物理存在。還可以在視圖的product_name
列上添加非聚集索引:
CREATE NONCLUSTERED INDEX
ucidx_product_name
ON production.product_master(product_name);
現在,如果根據視圖查詢數據,應該可以看到統計資訊已更改:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'product_master'. Scan count 1, logical reads 6, physical reads 1, read-ahead reads 11, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server現在不是從三個表中讀取數據,而是直接從物化視圖product_master
讀取數據。
請注意,此功能僅適用於SQL Server Enterprise Edition。 如果使用SQL Server Standard或Developer Edition,則必須直接在要使用視圖查詢的FROM
子句中使用WITH(NOEXPAND)
表提示,如下面的查詢:
SELECT
*
FROM
production.product_master WITH (NOEXPAND)
ORDER BY
product_name;