在學習70-433考試時,我注意到您能夠經過如下兩種方式之一建立覆蓋指數。 緩存
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
- 要麼 - 學習
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
INCLUDE子句對我來講是新的。 在肯定是否建立包含或不包含INCLUDE子句的覆蓋索引時,您將爲何使用它以及您會建議什麼準則? spa
若是該列不在WHERE/JOIN/GROUP BY/ORDER BY
,而僅在SELECT
子句中的列列表中。 code
INCLUDE
子句將數據添加到最低/葉子級別,而不是在索引樹中。 這使索引變小,由於它不是樹的一部分 排序
INCLUDE columns
不是索引中的關鍵列,所以它們沒有順序。 這意味着如上所述,它對於謂詞,排序等並非真正有用。 可是,若是在關鍵列的幾行中有剩餘查找,這可能會頗有用。 索引
基本索引列已排序,但包含的列未排序。 這樣能夠節省維護索引的資源,同時仍然能夠在包含的列中提供數據來覆蓋查詢。 所以,若是要涵蓋查詢,則能夠放置搜索條件以將行定位到索引的已排序列中,而後使用非搜索數據「包括」其餘未排序的列。 它絕對有助於減小索引維護中的排序和碎片數量。 資源
您可使用INCLUDE將一或多個列添加到非彙集索引的葉級,若是這樣作,則能夠「覆蓋」查詢。 get
假設您須要查詢員工的ID,部門ID和姓氏。 io
SELECT EmployeeID, DepartmentID, LastName FROM Employee WHERE DepartmentID = 5
若是您碰巧在(EmployeeID,DepartmentID)上具備非彙集索引,則在找到給定部門的員工後,如今必須進行「書籤查找」以獲取實際的完整員工記錄,而只是獲取「姓氏」列。 若是您找到不少員工,那麼就績效而言可能會很是昂貴。
若是您在索引中包含該姓氏:
CREATE NONCLUSTERED INDEX NC_EmpDep ON Employee(EmployeeID, DepartmentID) INCLUDE (Lastname)
那麼您須要的全部信息均可以在非彙集索引的葉級中找到。 只需查找非彙集索引並找到給定部門的員工,您便擁有了全部必要的信息,而且再也不須要爲索引中找到的每一個員工進行書籤查找->這樣能夠節省大量時間。
顯然,您不能在每一個非彙集索引中包括每一列-可是,若是您確實有一些查詢丟失了僅一到兩列以「被覆蓋」(而且被大量使用),那麼將那些包含在內將很是有幫助轉換爲合適的非彙集索引。
很好解釋了緣由(包括索引葉級中的數據)的緣由。 您對此進行兩點動搖的緣由是,當您運行查詢時,若是不包括其餘列(SQL 2005中的新功能),則SQL Server必須轉到彙集索引以獲取其餘列當新的數據頁被加載到內存中時,這將花費更多的時間,並增長SQL Server服務,磁盤和內存(特定於緩衝區緩存)的負載,從而有可能將其餘更經常使用的數據從緩衝區緩存中推出。
我在已經給出的答案中沒有看到的另外一個考慮因素是,包含的列能夠是不容許做爲索引鍵列的數據類型,例如varchar(max)。
這使您能夠將這些列包括在覆蓋索引中。 最近,我不得不執行此操做以提供nHibernate生成的查詢,該查詢在SELECT中具備不少列,並具備有用的索引。