開文之前首先要講講幾個概念
什麼是具有包含性列的索引?請看官方解釋:http://msdn.microsoft.com/zh-cn/library/ms190806%28SQL.90%29.aspx
覆蓋查詢】
當索引包含查詢引用的所有列時,它通常稱為“覆蓋查詢”。
索引覆蓋】
如果返回的資料列就包含於索引的索引值中,或者包含於索引的索引值+叢集索引的索引值中,那麼就不會發生Bookup Lookup,因為找到索引項目,就已經找到所需的資料了,沒有必要再到資料行去找了。這種情況,叫做索引覆蓋;
複合索引】
和複合索引相對的就是單一索引了,就是索引只包含一個欄位,所以複合索引就是包含兩個或者多個欄位的索引;
非鍵列】
鍵列就是在索引中所包含的列,當然非鍵列就是該索引之外的列了;
下面就開始今天的主題摘要1】
在 SQL Server 2005 中,可以通過將非鍵列添加到非叢集索引的分葉層級來擴充非叢集索引的功能。通過包含非鍵列,可以建立覆蓋更多查詢的非叢集索引。這是因為非鍵列具有下列優點:
* 它們可以是不允許作為索引鍵列的資料類型。
* 在計算索引鍵列數或索引鍵大小時,資料庫引擎不考慮它們。
當查詢中的所有列都作為鍵列或非鍵列包含在索引中時,帶有包含性非鍵列的索引可以顯著提高查詢效能。這樣可以實現效能提升,因為查詢最佳化工具可以在索引中找到所有列值;不訪問表或叢集索引資料,從而減少磁碟 I/O 操作。
說明:第一:只能是針對非叢集索引;第二:比起複合索引是有效能上的提升的,因為索引的大小變小了;
摘要2】
鍵列儲存在索引的所有層級中,而非鍵列僅儲存在分葉層級中。
說明:這就表現為包含與不包含的關係了。有關索引層級的詳細資料,請參閱表組織和索引組織。
摘要3】
使用包含性列以避免大小限制
可以將非鍵列包含在非叢集索引中,以避免超過當前索引大小的限制(最大鍵列數為 16,最大索引鍵大小為 900 位元組)。資料庫引擎計算索引鍵列數或索引鍵大小時,不考慮非鍵列。
例如,假設要為 AdventureWorks 樣本資料庫的 Document 表中的以下列建立索引:
Title nvarchar(50)
Revision nchar(5)
FileName nvarchar(400)
因為 nchar 和 nvarchar 資料類型的每個字元需要 2 個位元組,所以包含這三列的索引將超出 900 位元組的大小限制 10 個位元組 (455 * 2)。使用 CREATE INDEX 語句的 INCLUDE 子句,可以將索引鍵定義為 (Title, Revision),將 FileName 定義為非鍵列。這樣,索引鍵大小將為 110 個位元組 (55 * 2),並且索引仍將包含所需的所有列。下面的語句就建立了這樣的索引。
說明:當你把一個nvarchar(500)的欄位設定為主鍵的時候,你就可以看到不能超出900位元組的提示了。一般來說我們是不太會做這些操作的,所以那個錯誤提示也是不常見的,也許你可能還見過。
一個資料頁的大小才8k,所以我們合理的設定每個欄位的大小,不要浪費太多的空間,這樣對查詢也是有好處的,這個include就比較好的的解決了索引和空間的問題,雖然那些include的資料也會佔用空間。
雖然可以設定include,但是也盡量不要使用太多的欄位作為索引包含的非鍵列。
摘要4】
帶有包含性列的索引準則
設計帶有包含性列的非叢集索引時,請考慮下列準則:
* 在 CREATE INDEX 語句的 INCLUDE 子句中定義非鍵列。
* 只能對錶或索引檢視表的非叢集索引定義非鍵列。
* 除 text、ntext 和 image 之外,允許所有資料類型。
* 精確或不精確的確定性計算資料行都可以是包含性列。有關詳細資料,請參閱為計算資料行建立索引。
* 與鍵列一樣,只要允許將計算資料行資料類型作為非索引鍵之索引資料行,從 image、ntext 和 text 資料類型派生的計算資料行就可以作為非鍵(包含性)列。
* 不能同時在 INCLUDE 列表和鍵列列表中指定列名。
* INCLUDE 列表中的列名不能重複。
說明:include不能使用在叢集索引中。後面的兩點,這個在實際中很難想象會有這樣的需求要把重複列放到一個索引中。如果有朋友遇到過這樣的需求可以告知一些,不勝感激。那如果有是否可以通過不同的列名(其實儲存是同樣的值)來解決這個問題呢??