未建立 Indexed View 前的 TSQL 執行計畫
-- 建立 IX_SalesOrderDetail_ProductID,讓執行計畫單純一些
CREATE INDEX IX_SalesOrderDetail_ProductID ON Sales.SalesOrderDetail (ProductID)
INCLUDE (OrderQty, UnitPrice, UnitPriceDiscount)
WITH (DROP_EXISTING = ON)
SELECT
o.OrderDate ,
od.ProductID ,
SUM(od.UnitPrice * od.OrderQty * (1.00 - od.UnitPriceDiscount)) AS Revenue
FROM Sales.SalesOrderHeader AS o
JOIN Sales.SalesOrderDetail AS od ON o.SalesOrderID = od.SalesOrderID
WHERE od.ProductID BETWEEN 700 and 800
AND o.OrderDate >= '20130501'
GROUP BY o.OrderDate, od.ProductID
ORDER BY Revenue DESC;
GO
建立 Indexed View 限制
- 必須使用 WITH SCHEMABINDING
- 有 GROUP BY,必須包含 COUNT_BIG(*),且不能包含 HAVING
- 必須使用兩部分名稱 schema . tablename
- 檢視不可參考其他檢視
建立 Indexed View
-- 設定 Indexed View 設定
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING,
ANSI_WARNINGS,
CONCAT_NULL_YIELDS_NULL,
ARITHABORT,
QUOTED_IDENTIFIER,
ANSI_NULLS
ON;
DROP VIEW IF EXISTS Sales.vwOrdersStat
-- 建立使用 Schemabinding 的 View
CREATE OR ALTER VIEW Sales.vwOrdersStat
WITH SCHEMABINDING
AS
SELECT
o.OrderDate ,
od.ProductID ,
SUM(od.UnitPrice * od.OrderQty * (1.00 - od.UnitPriceDiscount)) AS Revenue
COUNT_BIG(*) AS COUNT
FROM Sales.SalesOrderHeader AS o
JOIN Sales.SalesOrderDetail AS od ON o.SalesOrderID = od.SalesOrderID
GROUP BY o.OrderDate, od.ProductID
GO
-- 建立 View 叢集索引後,該 View 即為 Index View
CREATE UNIQUE CLUSTERED INDEX IX_vwOrdersStat_OrderDate_ProductID
ON Sales.vwOrdersStat (OrderDate, ProductID);
GO
-- TSQL Query 中即使沒有在 From 中使用 Index View,仍然會觸發 Index View
SELECT
o.OrderDate ,
od.ProductID ,
SUM(od.UnitPrice * od.OrderQty * (1.00 - od.UnitPriceDiscount)) AS Revenue
FROM Sales.SalesOrderHeader AS o
JOIN Sales.SalesOrderDetail AS od ON o.SalesOrderID = od.SalesOrderID
WHERE od.ProductID BETWEEN 700 AND 800
AND o.OrderDate >= '20130501'
GROUP BY o.OrderDate, od.ProductID
ORDER BY Revenue DESC;
GO
範例中特別提到下列 TSQL 也會跑 Indexed View,因為有用到 Indexed View 的第一個欄位,假如只對 ProductID 進行彙總的話,就無法囉
SELECT
o.OrderDate ,
SUM(od.UnitPrice * od.OrderQty * (1.00 - od.UnitPriceDiscount)) AS Revenue
FROM Sales.SalesOrderHeader AS o
JOIN Sales.SalesOrderDetail AS od ON o.SalesOrderID = od.SalesOrderID
WHERE od.ProductID BETWEEN 700 AND 800
AND o.OrderDate >= '20130501'
GROUP BY o.OrderDate
ORDER BY Revenue DESC;
GO
- 參考資料
- [SQL SERVER][Performance]善用Indexed View - 簡介、測試
- [SQL SERVER][Performance]NOEXPAND Hint
- [SQL SERVER]謹慎使用索引檢視
- 建立索引檢視(Indexed View)來提高查詢效能
- 強制SQL引擎利用Index View資料做查尋
- SQL Server Indexed Views: The Basics
- 浅谈SQL Server索引视图(物化视图)以及索引视图与查询重写












![[X.Form] 呼叫 WebApi 下載圖片](https://live.staticflickr.com/65535/50002178622_b578fd1147_z.jpg)
![[WebApi] 下載圖片-1](https://live.staticflickr.com/65535/50002087602_6b3755c7c2_z.jpg)
![[WebApi] 下載圖片-2](https://live.staticflickr.com/65535/50001834781_ae3c95dec8_z.jpg)
![[X.Form] HttpClient 抓取 API 資料-2](https://live.staticflickr.com/65535/49986194718_78cc2d762b.jpg)
![[X.Form] HttpClient 抓取 API 資料-1](https://live.staticflickr.com/65535/49986174878_e3c6ccd73e_z.jpg)
![[VS] 選擇性貼上-1](https://live.staticflickr.com/65535/49986842242_ecd6da2f89_z.jpg)
![[X.Form] Messaging Center-1](https://live.staticflickr.com/65535/49979121898_7f17894e33_w.jpg)


![[SQL] 複合索引欄位順序影響 - 選擇性-1](https://live.staticflickr.com/65535/49962879833_4aca1726a9.jpg)
![[SQL] 複合索引欄位順序影響 - 選擇性-2](https://live.staticflickr.com/65535/49962879848_99dd5764f7_z.jpg)
![[SQL] 複合索引欄位順序影響 - 選擇性-3](https://live.staticflickr.com/65535/49963055173_8544e1002f_z.jpg)
![[C#] 更新主執行緒控件-1](https://live.staticflickr.com/65535/50349106306_caa4786015_w.jpg)
![[C#] 執行緒更新控件-2](https://live.staticflickr.com/65535/49958639682_0601ac915d_z.jpg)
![[C#] 更新主執行緒控件-3](https://live.staticflickr.com/65535/50348409768_058c2021ec_w.jpg)
![[C#] 更新主執行緒控件-4](https://live.staticflickr.com/65535/50349106346_33eaa18cdb_w.jpg)
![[C#] 更新主執行緒控件-5](https://live.staticflickr.com/65535/50349291792_44071c4a30_z.jpg)