【翻譯】SQL Server索引進階:第一級,索引簡介

來源:互聯網
上載者:User

原文地址:

Stairway to SQL Server Indexes: Level 1, Introduction to Indexes

本文是SQL Server索引進階系列Stairway to SQL Server Indexes)的一部分。

索引是資料庫設計的基礎,向開發人員顯示了使用資料庫大量資料庫設計者的意圖。不幸的是,索引大部分時候是在出現效能問題的時候,才被事後添加上的。

第一級介紹一下SQL Server的索引:是一種資料庫物件,使得SQL Server可以在最短的時間內查詢 or 修改請求的資料,使用最少的系統資源帶來最大的效能提升。好的索引將會允許SQL Server實現最大化的並發,一個使用者的查詢對於其他使用者的查詢幾乎沒有影響。最終,索引給資料庫完整性提供一種高效的方式,當唯一索引建立的時候,確保唯一的索引值。這一級只是一個簡介,包括一些理論和使用,一些物理的細節留在後面的層級中介紹。

對於資料庫開發人員來說,徹底的理解索引是重要的,當一個請求從用戶端到達SQL Server,SQL Server只有兩種可能的路徑來訪問請求的資料行:


第一種方法對於SQL Server來說總是可用的,第二種方法只在你給資料庫設計了可用的索引的情況下才是可行的,但是第二種可以帶來極大地效能提升,接下來我們將繼續介紹。

因為索引需要維護它們會佔用物理空間,並且它們一定會和表保持同步),所以它們不是SQL Server必須的。有的資料庫會完全沒有索引。它們可能會導致效能下降,有可能帶來資料完整性問題,但是SQL Server允許它的存在。

但是,這些不好的不是我們想要的。我們都希望資料庫效能優良,資料完整,同時,保持索引維護的最小化。本層級將會朝著這個目標引導大家。



資料庫執行個體



貫穿整個進階系列,我們都會使用執行個體來闡述關鍵的理念。這些例子使用的是微軟的 AdventureWorks 樣本資料庫。我們主要使用銷售訂單部門。包含5張表:Customer, SalesPerson, Product, SalesOrderHeader, SalesOrderDetail。為了保持注意力的集中,我們使用部分的列。

AdventureWorks 設計的很規範,銷售人的資訊在三張表中都有:SalesPerson,Employee,Contact。在某些情況下,我們會把他們看成是一張表。是這些表之間的關係。

650) this.width=650;" border="0" alt="" src="http://www.bkjia.com/uploads/allimg/131229/19304M925-0.jpg" />



本層級用到的TSQL在後面都會給出。



什麼是索引



通過一個小故事開始我們的索引學習之旅,一個很老,但是證明很技術,貫穿整篇本章,介紹索引的基本概念。

你離開家去處理一些事情。當你回來的時候,從等待你回來的女兒的壘球教練口中得到一些訊息。三個女孩子:Tracy, Rebecca, and Amy弄丟了他們的帽子。你能否給他們買帽子,下一場比賽他們的父母將會還給你。

你認識那些女孩子,也認識他們的父母。但是你不知道他們帽子的尺寸。在你家的鎮子上有三家人,每家都有一些你需要的資訊。沒有問題,你會打電話給他們,得到帽子的尺寸。你一手拿著電話,一邊開啟電話本的目錄索引。

你需要聯絡的第一家是Hellen Meyer,你估計Meyer應該在姓名的中部,你直接跳到電話本的中間部分,但是你發現來到了頁頭部寫著“Kline-Koerber”的一頁,向前翻了幾頁,又發現了“Nagle-Nyeong”,又向前翻了幾頁,發現了“Maldonado-Nagle”。意識到你快要找到了,向後尋找,你找到了“Meyer,Helen”一行,找到的對應的號碼。打通了Meyer的家,得到了你想要的資訊。

重複上面的過程,找到了另外兩個家庭,擷取了另外兩個帽子的尺寸。

你使用了索引,你使用索引的方式和SQL Server使用索引的方式類似。他們有很多的相似,有一些不同,電話本和SQL Server的索引。

事實上,你剛才使用的就是SQL Server兩種索引聚集和非聚集)中的一種,非叢集索引。本層級我們介紹非叢集索引,下一層級介紹叢集索引,以及深入的分析這兩種索引。



非叢集索引



白紙類似非叢集索引,他們不是以資料本身來組織的,只是一個映射,協助你訪問資料。資料本身才是我們真正需要的。電話公司沒有將鎮子的居民整理到一個有意義的隊列中,將房子從一個地方移動到另一個地方,方便同一個壘球隊的女孩們的家是一個挨一個的,而不是像現在這樣用居民的姓氏來組織。相反,他給你一本書,包含每個居民。每行都包含一個鍵,使得你可以訪問到居民的電話。

就像白紙上的電話一樣,SQL Server的非叢集索引都包含兩部分的內容:

查詢鍵,例如:姓氏-名稱-中間部分這樣的格式,在SQL Server的詞彙中,叫做索引鍵。

標籤,提供相同的內容,那就是電話號碼,SQL Server中則直接指向鍵代表的資料行。

另外,一個SQL Server非叢集索引還會包含一些內部使用的頭部資訊,可能會包含一些可選的資訊。這些內容在後面的層級中會有介紹,現在還不是理解非叢集索引的重點內容。

就像電話本一樣,SQL Server的索引維護一個查詢鍵,經過幾次小的跳轉就會找到想要訪問的入口。給出一個查詢鍵,SQL Server可以快速的定位入口。不像電話本,SQL Server的索引是動態。那就是說,每次增加一行,刪除一樣,或者是包含查詢鍵的一列被修改,SQL Server都會更新索引。

就像在電話本上兩個挨著的家庭,在地理位置上不是挨著的一樣,在非叢集索引中挨著的兩個入口,也不是表中挨著的兩行資料。第一個入口可能是表中的最後一行,第二個入口可能是表中的第一行。事實上,不想索引,入口通常是有意義的序列。表中的行是完全無序的。

當我們建立一個索引,SQL Server會產生並且在額外的表中精確的維護每一行的入口。在一張表可以建立多於一個的非叢集索引。

最大的不同是:SQL Server不能使用電話。他只會使用標籤中的資訊,才可以導航到對應的表中的行。



建立並且從非叢集索引中受益



我們通過兩次樣本資料庫的查詢來結束這個層級,確保你使用的樣本資料庫是SQL Server 2005的AdventureWorks 資料庫,也可以是SQL Server 2008。每次我們會執行相同的查詢,但是第一次是在建立索引之前,第二次是在建立索引之後。每一次,SQL Server都會告訴我們擷取資料需要做多少工作。我們將在Contact表中查詢Helen Meyer行大概在表的中間部分)。初始時候,在FirstName或者是LastName列沒有索引,為了確保執行正確,可以通過下面的代碼來刪除索引。

 

 
  1. IF EXISTS (SELECT * FROM sys.indexes 
  2. WHERE OBJECT_ID = OBJECT_ID('Person.Contact') 
  3. AND name = 'FullName') 
  4. DROP INDEX Person.Contact.FullName;  



開啟IO和時間統計

 

 
  1. SET STATISTICS io ON 
  2. SET STATISTICS time ON 
  3. GO 



執行查詢

 

 
  1. SELECT * 
  2.     FROM Person.Contact 
  3.     WHERE FirstName = 'Helen' 
  4.         AND LastName = 'Meyer'; 
  5. GO 



我們會看到執行結果,也就是Helen的資訊。

在訊息tab中我們會看到
 

 
  1. 表 'Contact'。掃描計數 1,邏輯讀取 561 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。 
  2.  
  3. SQL Server 執行時間: 
  4.    CPU 時間 = 0 毫秒,佔用時間 = 9 毫秒。 



資訊中顯示本次查詢產生邏輯IO 561次,處理器佔用9毫秒的時間。你顯示的內容會和處理器的不同而不同。

建立非叢集索引

 

 
  1. CREATE NONCLUSTERED INDEX FullName 
  2.             ON Person.Contact 
  3.     ( LastName, FirstName ); 
  4. GO 


再次執行查詢

 

 
  1. SELECT * 
  2.     FROM Person.Contact 
  3.     WHERE FirstName = 'Helen' 
  4.         AND LastName = 'Meyer'; 
  5. GO 



這次看到的資訊變成了
 

 
  1. 表 'Contact'。掃描計數 1,邏輯讀取 4 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。 
  2.  
  3. SQL Server 執行時間: 
  4.    CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。 



建立索引之後只需要4次邏輯IO,更少的處理器佔用時間。
 


結論



建立合適的索引可以極大的提升資料庫效能。在下一層級,我們會瞭解索引的物理結構。我們將會知道非叢集索引為什麼會對查詢有好處。還會介紹其他類型的索引,索引的其他好處,索引相關的代價,監控和維護索引,和一些最佳實務。目標就是告訴你建立索引所必須的知識。



代碼下載

 

  • Level 1 - IntroToIndexes_Durant_Code.sql
  • Level 1 - MillionRowContactTable.sql



 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.