- "Indexed View" 的使用方式
- 資料庫使用 Adventure Works for SQL Server 2012 的資料表 Sales.SalesOrderHeader 及 Sales.SalesOrderDetail 產生 1 個 View 包含 "Clustered"
- 創建指令
- "With Schemabinding" 建立的 VIEW ,才可以建立索引
- 需遵守 "兩部份名稱" (SchemaName.TableName 格式)
- "Indexed View" 不可參考其他檢視表
- 第一個建立的索引,必須是 "Unique Clustered Index",之後可建立其他 "NonClustered Index"
- 使用 "Group By"時,必須輸出 COUNT_BIG(*) 規定,返回指定組中的項目數量
use AdventureWorks2012;
if OBJECT_ID('vwSalesOrderAmt', 'view') is not null
drop view vwSalesOrderAmt;
GO
create view vwSalesOrderAmt With Schemabinding as
select h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate,
sum(d.OrderQty * d.UnitPrice * (1 - d.UnitPriceDiscount)) AmtTotal,
COUNT_BIG(*) CB
from Sales.SalesOrderHeader h
join Sales.SalesOrderDetail d ON h.SalesOrderID = d.SalesOrderDetailID
group by h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate
GO
create Unique Clustered index clIndex ON vwSalesOrderAmt (SalesOrderID)
GO
SELECT h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate,
SUM((d.OrderQty * d.UnitPrice) * (1 - d.UnitPriceDiscount)) AS AmtTotal,
COUNT_BIG(*) AS CB
FROM Sales.SalesOrderHeader AS h
INNER JOIN Sales.SalesOrderDetail AS d ON h.SalesOrderID = d.SalesOrderDetailID
GROUP BY h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate
USE AdventureWorks2012 ;
GO
EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE ;
GO
EXEC sp_configure 'index create memory (KB)', 2048 ;
GO
RECONFIGURE;
GO
select h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate,
sum(d.OrderQty * d.UnitPrice * (1 - d.UnitPriceDiscount)) AmtTotal
from Sales.SalesOrderHeader h
join Sales.SalesOrderDetail d ON h.SalesOrderID = d.SalesOrderDetailID
where h.SalesOrderID = 43659
group by h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate
- CASE 2:
- 查詢
- 若不是使用 SQL Server 2008 企業版或開發版,必須加上 WITH(NOEXPAND)
- "Indexed View" 只使用 "單一資料表" 時,必須加上 table hints 的 "WITH(NOEXPAND)",告訴 Query Optimizer 此檢視表是獨立於底層資料表,否則 Query Optimizer 還是會採用原有的底層資料表,而不使用 "WITH(NOEXPAND)"
select h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate,
sum(d.OrderQty * d.UnitPrice * (1 - d.UnitPriceDiscount)) AmtTotal
from Sales.SalesOrderHeader h
join Sales.SalesOrderDetail d ON h.SalesOrderID = d.SalesOrderDetailID
where h.SalesOrderID = 43659
group by h.SalesOrderID,
h.OrderDate,
h.DueDate,
h.ShipDate
select * from vwSalesOrderAmt WITH(NOEXPAND) where SalesOrderID = 43659
- 查詢結果
- 查詢 2:所使用 "Indexed View" 查詢成本很低
- Result:
查詢的所有條件符合 "Indexed View"的條件,Database Engine 就會使用 "Indexed View"
- "Indexed View" 不會有額外的 "查閱" 成本,"Indexed View" 本身含有資料行與資料列,不像一般的檢視表
- 如 "Indexed View" 參考資料有異動,"Indexed View" 會自動同步更新,不用擔心使用過期的資料
- REF:
沒有留言:
張貼留言