2010-12-10 24 views
1

我創建索引視圖(上Table1_ID聚集唯一索引)鑑於這樣的T-SQL:瞭解索引視圖更新QND查詢過程2008 R2

Select Table1_ID, Count_BIG(*) as Table2TotalCount from Table2 inner join 
Table1 inner join... where Table2_DeletedMark=0 AND ... Group BY Table1_ID 

而且在創建視圖之後,我們設置羣集獨特列Table1_ID上的索引。
所以查看由兩列組成:

Table1_ID 
Table2TotalCount 

T-SQL創建視圖是因爲幾百萬的表2中的行組和沉重。

但是當我運行一個查詢,視圖像

Select Total2TotalCount from MyView where Table1_ID = k 

- 它執行速度快,無開銷的服務器。

同樣在t-sql中創建視圖的許多條件在where子句中爲Table2列。而 如果我改變Table2_DeletedMark爲1,然後再次運行查詢

Select Total2TotalCount from MyView where Table1_ID = k 

- 我會得到正確的結果。 (Table2TotalCount減1)。

因此,我們的問題是:
1.爲何查詢執行時間減少很多,所以,當我們使用索引視圖
2(與不使用視圖(即使我們執行查詢查看)之前運行DBCC DROPCLEANBUFFERS())。改變後

Table2_DeletedMark 

查看立即重新計算,我們得到正確的結果,但後面的過程是什麼?我們無法想象sql每次更改包含在t-sql視圖生成中的10列以上的任何值時生成的視圖都會執行t-sql,因爲它太重了。
我們知道,運行簡單的查詢來重新計算值就足夠了,這取決於我們更改的列值。
但sql如何理解呢?

回答

2

索引視圖是物化例如,它所包含的行(取決於它所依賴的表)是在物理上存儲在磁盤上的--就像「系統計算」表一樣,只要它的基礎表發生變化,它就始終保持最新狀態。這是通過添加聚集索引來完成的 - 在SQL Server表(或視圖)上的聚簇索引的葉頁是的數據頁,真的。

索引視圖中的列也可以使用非聚簇索引編制索引,因此您可以更進一步提高查詢性能。缺點是:由於行被存儲,所以你需要磁盤空間(顯然一些數據是重複的)。

另一方面,普通視圖只是SQL的一個片段,將根據您從該視圖中選擇的內容執行以計算結果。該視圖沒有物理表示,沒有爲常規視圖存儲的行 - 它們需要根據需要從基表中連接在一起。

+0

我知道索引視圖是物化的。主要問題是我們的第二個問題。我想知道一種機制可以用於「每當基礎表發生變化時始終保持最新狀態」。怎麼運行的 ?你能解釋一下問題2 – 2010-12-10 11:41:02

+0

@ mmcteam.com.au:除了來自SQL Server團隊的人以外,我不認爲任何人都可以真正解釋它是如何工作的。我只知道它確實有效 - 每當更改任何基礎表時,索引視圖都會更新。這就是我需要了解的一切:-) – 2010-12-10 12:01:13

0

爲什麼你認爲在索引視圖中允許的內容有多麼奇怪的規則,以及基表允許做什麼?SQL引擎可以立即知道「如果我觸及這一行,它可能會影響這個視圖的結果 - 讓我們看看,這行不再符合視圖標準,但我堅持要有一個COUNT_BIG(*),所以我可以減少一個值「