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


原文地址:

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只有兩種可能的路徑來訪問請求的數據行:

  1. 掃描包含數據的表中的每一行,從第一行到最后一行,檢查每一行是否滿足請求的條件。
  2. 如果包含可用的索引,可以用索引來定位請求的數據。


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

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

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



數據庫實例



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

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



本級別用到的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,更少的處理器占用時間。
 


結論



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


代碼下載

 

其他文章


【翻譯】SQL Server索引進階:第二級,深入非聚集索引

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM