時間過得真快——再過幾分鐘,你就要完成第2個月的性能調優培訓。今天這部分培訓我想講下非彙集索引的更多信息,還有你會碰到它的一些負做用。html
上一星期咱們討論了SQL Server裏的書籤查找,它是很是危險的。在執行計劃裏SQL Server訪問非彙集索引時,額外列必需要從表自己獲取時(由於它們不是非彙集索引的一部分),書籤查找會發生。若是你想避免書籤查找,你能夠在SQL Server裏定義覆蓋索引(Covering Index ) 。咱們來看下。post
在SQL Server裏覆蓋索引是傳統的非彙集索引。惟一的區別是覆蓋非彙集索引能夠包含給出查詢全部須要的列。這就是說使用覆蓋索引能夠避免書籤查找。咱們來看一個很是簡單的例子。下列的查詢會產生書籤查找,由於PostalCode列不是非彙集索引IX_Address_StateProvinceID 的一部分,在執行計劃裏,這個非彙集索引已被使用。性能
1 SELECT 2 AddressID, 3 PostalCode 4 FROM Person.Address 5 WHERE StateProvinceID = 42 6 GO
這個查詢自己產生18個邏輯讀。你能夠經過定義覆蓋非彙集索引,拿掉這個查詢的書籤查找。就是說,咱們須要包含PostalCode 列,在非彙集索引的葉子層。學習
1 CREATE NONCLUSTERED INDEX idxAddress_StateProvinceID ON 2 Person.Address (StateProvinceID) 3 INCLUDE (PostalCode) 4 GO
當你再次執行這個查詢時,從執行計劃裏你能夠看到書籤查找已經不見了,SQL Server使用索引查找(非彙集索引)運算符。邏輯讀減小爲2個。很是顯著的性能提高!url
惟一你要知道的是,並非每一個書籤查找都是很是危險的。咱們的目標不是移除每一個書籤查找,只有壞的才移除。spa
在一些狀況下,當SQL Server對指定查詢進行書籤查找操做時,它能夠決定書籤查找太耗資源了(根據必須的邏輯讀)。在那個狀況下,SQL Server會進行全表掃描,而忽略全部的非合格列。作出這個決定點位置,在SQL Server裏被稱爲臨界點(Tipping Point)。臨界點就是SQL Server用來決定是進行書籤查找仍是全表掃描。code
臨界點躲在你查詢須要讀取頁數的1/4到1/4的某個位置。這和你須要讀取的記錄數無關(由於記錄的大小決定了1頁裏你能夠存放多少記錄)。對於這個很是簡單的例子,我定義的表裏每條記錄長度是400 bytes長,這就是在8k的頁裏能夠存放20條記錄。另外我在Value列定義了一個非彙集索引。下面的查詢使用書籤查找返回1061條記錄。htm
1 SELECT * FROM Customers 2 WHERE Value < 1062 3 GO
若是獲取更多一條記錄,做爲特殊狀況的下面查詢就會臨界點上,而後SQL Server就會掃描整個表。blog
1 SELECT * FROM Customers 2 WHERE Value < 1063 3 GO
2個近乎同樣的查詢,卻有徹底不一樣的執行計劃!這在某些狀況下會是個巨大的問題,由於你的計劃穩定性再也不。過去幾年我與不少不一樣客戶打交道時,由於這個問題,它們的SQL Server近乎發瘋。SQL Server臨界點遊戲——爲何非彙集索引被忽略!索引
在這一部分的性能調優培訓裏,你學習了SQL Server裏的覆蓋非彙集索引還有臨界點。在你學習的4個星期裏,索引在SQL Server裏能夠說是個很神奇的東西!
每一個索引在提升你讀性能的同時,也會下降你的寫性能。在你執行INSERT, UPDATE和DELETE語句時, 每一個索引都由SQL Server全權負責維護。所以,你要基於讀需求和寫工做量來平衡你的索引策略。
接下來的4個星期,咱們會聚焦更多SQL Server裏的執行計劃,你會學到如何讀懂和理解執行計劃,還有它們如何用來作性能調優。請繼續關注,下週見!