
(資料圖片僅供參考)
視圖是一個包含了一個或多個表的數(shù)據(jù)列的虛擬表。通常情況下,它僅僅是存儲了查詢的對象,一個視圖可以當(dāng)作一個表,可以用于存儲過程、JOIN、用戶自定義函數(shù)等等。
視圖包含了下面兩個主要特性:
1.提供了一個安全機制,用于限制用戶只能訪問特定的數(shù)據(jù)。2.使得開發(fā)人員能定制用戶的邏輯視圖。
當(dāng)你查詢一個視圖時,優(yōu)化器會產(chǎn)生一個單一的執(zhí)行計劃給這個查詢。在索引視圖未出現(xiàn)之前,視圖必須解決查詢在執(zhí)行期間才硬化。所有的JOIN、聚合都在運行時才發(fā)生,當(dāng)創(chuàng)建了索引視圖之后,視圖的結(jié)果就會在創(chuàng)建時物化并以物理方式存儲在數(shù)據(jù)庫中。減少了運行大表上的復(fù)雜查詢的開銷。
在開始索引視圖之前,需要先決定哪些列需要包含在索引視圖中,如何選擇候選碼等等:
1.視圖不能引用其他視圖。2.視圖要引用什么基礎(chǔ)表。3.列名必須明確定義別名。
而它的缺點是:
1.耗費硬盤空間存放。2.在DML語句如增刪改的時候,索引創(chuàng)建會有開銷,因為這些一旦執(zhí)行,索引必須隨機更新。3. 維護開銷。
在決定創(chuàng)建索引視圖之前,最好標(biāo)識一下select語句將會使用多少列。如果小范圍的select語句將要使用,如果表不穩(wěn)定且經(jīng)常要更新,那么創(chuàng)建索引視圖并不是件好事。通常情況下,經(jīng)常JOIN或者聚合,且表很大的查詢,可以考慮使用索引視圖。但是由于它的某些限制,并不適合在OLTP中過度使用。
在創(chuàng)建之前有些SET選項需要配置:
1.ARITHABORT2.CONCAT_NULL_YIELDS_NULL3.QUOTED_IDENTIFIER4.ANSI_WARNINGS5.ANSI_NULLS6.ANSI_PADDING7.NUMERIC_ROUNDABORT——OFF,其他為ON。
USE AdventureWorks2012 GO CREATE VIEW POView WITH SCHEMABINDING AS SELECT POH.PurchaseOrderID , POH.OrderDate , emp.LoginID , v.name AS VendorName , SUM(POD.OrderQty) AS OrderQty , SUM(POD.OrderQty * POD.UnitPrice) AS Amount , COUNT_BIG(*) AS [Count] FROM Purchasing.PurchaseOrderHeader POH INNER JOIN Purchasing.PurchaseOrderDetail AS POD ON POH.PurchaseOrderID = POD.PurchaseOrderID INNER JOIN HumanResources.Employee AS EMP ON poh.EmployeeID = EMP.BusinessEntityID INNER JOIN Purchasing.Vendor AS V ON POH.VendorID = v.BusinessEntityID GROUP BY POH.PurchaseOrderID , POH.OrderDate , emp.LoginID , v.Name GO CREATE UNIQUE CLUSTERED INDEX IndexPOView ON POView(PurchaseOrderID) GO
SELECT TOP 10 POH.PurchaseOrderID , POH.OrderDate , emp.LoginID , v.name AS VendorName , SUM(POD.OrderQty) AS OrderQty , SUM(POD.OrderQty * POD.UnitPrice) AS Amount , COUNT_BIG(*) AS [Count] FROM Purchasing.PurchaseOrderHeader POH INNER JOIN Purchasing.PurchaseOrderDetail AS POD ON POH.PurchaseOrderID = POD.PurchaseOrderID INNER JOIN HumanResources.Employee AS EMP ON poh.EmployeeID = EMP.BusinessEntityID INNER JOIN Purchasing.Vendor AS V ON POH.VendorID = v.BusinessEntityID GROUP BY POH.PurchaseOrderID , POH.OrderDate , emp.LoginID , v.Name go SELECT TOP 10 * FROM POView WITH ( NOEXPAND )
可以看出,普通查詢的開銷是索引視圖的9倍(不是絕對值),因為第一個查詢使用了多個索引,而第二個查詢只用了一個。
對于應(yīng)用程序來說,視圖是否是索引視圖,都對源程序沒有影響,優(yōu)化器會自動優(yōu)化這些步驟,有時候優(yōu)化器會選擇直接訪問表上的索引而不是使用索引視圖,在測試環(huán)境中,可以直接測試查詢或者索引視圖。如果優(yōu)化器使用了表上的索引,也可以強制使用WITH NOEXPAND提示來限定使用索引,僅當(dāng)查詢優(yōu)化器確定在 SQL Server 的查詢計劃中使用索引視圖有益時,SQL Server 才會選擇WITH NOEXPAND。
索引視圖必須使用WITHSCHEMABINDING選項,以便視圖引用的表不會被隨意修改甚至刪除。索引視圖不支持HAVING,CUBE和ROLLUP。
標(biāo)簽: 過度使用