在前面我們已經提到過有關視圖的下述觀點:由於視圖返回的結果集與具有行列結構的表有著相同的表格形式,並且我們可以在SQL 陳述式中像參考資料表那樣引用視圖,所以我們常把視圖稱為虛表。標準視圖的結果集並不以表的形式儲存在資料庫中,而是在執行引用了視圖的查詢時,SQL Server 2000 才把相關的基本表中的資料合併成視圖的邏輯結構。
上面的結論常讓我們產生這樣的焦慮:由於是在執行了引用了視圖的查詢時,SQL Server 2000 才把相關的基本表中的資料合併成視圖的邏輯結構,那麼當查詢所引用的視圖包含大量的資料行或涉及到對大量資料行進行合計運算或串連操作,毋庸置疑,動態地建立視圖結果集將給系統帶來沉重的負擔,尤其是經常引用這種大容量視圖。
解決這一令人頭痛問題的方法就是為視圖建立聚簇索引,只有這樣才會顯著地提高系統的效能。當在視圖上建立了聚簇索引後,視圖的結果集與有聚簇索引的表的資料集一樣是儲存在資料中的。
此外,在視圖上建立索引還會帶來這樣的好處;最佳化器可以在那些在FROM 從句中不直接命名視圖的查詢中使用視圖索引,而且對已存在的視圖而言,由於不必重新編寫查詢代碼,從而提高了查詢從索引檢視表中檢索資料的效率。
如果在視圖上建立索引,那麼視圖中的資料會被立即儲存在資料庫中,對索引檢視表進行修改,那麼這些修改會立即反映到基礎資料表中。同理,對基礎資料表所進行的資料修改也會反映到索引檢視表那裡。索引的惟一性大大提高了SQL Server 尋找那些被修改的資料行。
維護索引檢視表比維護基礎資料表的索引更為複雜。所以,如果認為值得以因資料修改而增加系統負擔為代價來提高資料檢索的速度,那麼應該在視圖上建立索引。在為視圖建立索引前,視圖本身必須滿足以下條件: 在執行CREATE VIEW 命令時,必須將ANSI_NULLS 和QUOTED_IDENTIFIER選項設定為ON 狀態; 在使用CREATE TABLE 命令建立索引所引用的基礎資料表時,ANSI_NULLS 選項應設定為ON; 該視圖所引用的對象僅包括基礎資料表而不包括其它的視圖; 視圖所引用的基礎資料表必須與視圖同屬於同一資料庫且有相同的所有者; 在建立視圖時必須使用SCHEMABINDING 選項; 如果視圖引用了使用者自訂函數,那麼在建立這些使用者自訂函數時也必須使用SCHEMABINDING 選項 ; 視圖必須以owner.objectname 的形式來使所引用的表或使用者自訂函數; 視圖所引用的函數必須是確定性; 另外值得注意的是,在建立視圖的SELECT 語句中不應該包含下面的Transact-SQL文法; SELECT 語句中不能使用*或tablename.*來定義列,必須直接給出列名,否則不可以; 表示行集合的函數; UNION、 DISTINCT、 TOP、 ORDER BY、 COMPUTE、 COMPUTE BY、COUNT(*) 等; AVG、 MAX、 MIN、 STDEV、 STDEVP、 VAR 和VARP 等合計運算函數。
通常而言,可以在視圖上建立多個索引,但是應該記住,在視圖上所建立的第一個索引必須是聚簇索引,然後才可以建立其它的非聚簇索引。
在第八章我們已經詳細介紹了CREATE INDEX 命令但是如果準備為視圖建立索引那麼在執行該命令以前您必須確保以下條件否則建立將會失敗。 CREATE INDEX 命令的執行者必須是視圖的所有者; 在執行建立索引命令期間,ANSI_NULLS、 ANSI_PADDING、 ANSI_WARNINGS、ARITHABORT、 CONCAT_NULL_YIELDS_NULL、 QUOTED_IDENTIFIERS 諸選項應被設定成ON 狀態; NUMERIC_ROUNDABORT 選項被設定為OFF 狀態; 視圖不能包括text、 ntext、 image 類型的資料列; 如果視圖的SELECT 語句中包含ORDER BY 選項,則聚簇索引的關索引值只能是ORDER BY 從句中所定義的資料列。
在視圖上建立了索引之後,如果打算修改視圖資料,則應該保證修改時的選項設定與建立索引時的選項設定一樣,否則SQL Server 將產生錯誤資訊,並復原所做的INSERT、UPDATE 和DELETE 操作。