SQL索引學習-索引結構

前一陣無心中和同事討論過一個SQL相關的題(經過一個小問題來學習SQL關聯查詢),很慚愧一個很是簡單的問題因爲種種緣由竟然沒有回答正確,數據庫知識方面我算不上技術好,談起SQL知識的學習我得益於2008年進的一家公司,有幾個DBA技術至關專業,正好手上有一個項目遇到了一些數據庫查詢性能問題,就試着想辦法優化,因而本身將相法和DBA溝通後,竟然獲得了他們的贊同,讓我信心大增,後來一段時間我又主動找他們聊了一些其它的知識,因此在數據庫索引這塊我算是相對通常的.net程序員要更加有看法一些。當時咱們部門因爲分工的不一樣,部門20多人基本上工做中歷來不和SQL打交道,後臺的接口都由其它部門來完成了,咱們注意的 業務邏輯,因此有一些徹底不懂SQL的程序員。以後的四年我大部分都是作一些通用平臺架構方面的工做,也比較少直接接觸SQL,直到後來換了公司,特別是去年開始因爲項目性質的變化,我開始慢慢又開始接觸SQL。    html

工做時間的長短在某種程度上能決定一我的的技術水平,但每每技術水平和實際工做的產出不必定成正比。好比我上面提到那個SQL問題,不少有經驗的程序員在第一個答案中每每回答錯誤,但他確實能將項目作好,由於你們平時觀注的仍是結果,只要結果出來了比什麼都強,至於爲何出這樣的結果通常也就不會多作分析研究。這種形式呢,對那些對技術提高沒有強烈要求的人來說,已經夠用了,多試幾回,只要最終能出結果也就萬事大吉了,作的多了,後續遇到相似的問題也就輕車熟路了,這就是所謂的經驗,只知道這樣作就能出結果。    程序員

其實這種工做學習方式呢,有一個比較顯著的問題,就是對本身寫出來的東西沒有足夠的信心,由於靠的是以往的經驗。是出現錯誤以後經過不斷的嘗試來取得的經驗,有一種探索的味道,在工做效率上會存在問題,由於總有你之前沒有遇到過的場景,這樣你可能對第一方案作屢次嘗試才找到正解,反之的話,第一個方案可能花的時間稍長一些,但後續反覆修改的次數會至關較少。算法

SQL索引目錄   sql

藉此次機會呢,將SQL索引的理解整理出來,供你們一塊兒學習提升,這是個人學習筆記,有錯誤的地方,歡迎你們批評指正。下面是預計的目錄:數據庫

  • 索引基礎知識  
  • 彙集索引  
  • 非彙集索引  
  • 認識執行計劃  
  • 靈活設計數據庫      

頁和區

要想作好索引優化,知道索引的存儲結構是相當重要的。談到存儲就須要瞭解SQL中的頁和區的概念:  架構

  • SQL中存儲數據的基礎單位就是頁,一個頁大小爲8K,數據庫能夠將數據從邏輯上分紅頁,磁盤的I/O操做就是在頁級執行。頁包信三項內容:
    • 96字節大小的標頭,存儲統計信息,包括頁碼、頁類型、頁的可用空間以及擁有該頁的對象的分配單元 ID。頁類型咱們知識以下三項基本就夠用:
      • 數據頁,除了大型對象的數據列以外的數據存儲頁,好比int,float,varchar等。     
      • 索引頁,存放索引的條目。
      • 大型對象數據類型,好比text,image,nvarchar(max)等。        
    • 數據行
    • 行偏移量
  • 一個區包含8個頁,它是管理空間的單位,分爲以下兩類
    • 統一區,由單個對象全部。
    • 混合區,最多可由八個對象共享。
  • 通常狀況下,給表或者索引伸請新的空間時,從混合區分配,當這個表或者索引的空間超過8個頁大小時,會將本來在混合區的頁轉移到統一區管理。

表存儲結構

知識了區以及頁的概念,再看下數據表和這二者之間的聯繫, 表包含一個或多個分區,每一個分區在一個堆或一個彙集索引結構中包含數據行。從下圖的結構中,咱們就看到了索引的重要結構B-樹了。佈局

            

 

彙集索引結構

索引中的底層節點稱爲葉節點。根節點與葉節點之間的任何索引級別統稱爲中間級。在彙集索引中,葉節點包含基礎表的數據頁。根節點和中間級節點包含存有索引行的索引頁。每一個索引行包含一個鍵值和一個指針,該指針指向 B -樹上的某一中間級頁或葉級索引中的某個數據行。每級索引中的頁均被連接在雙向連接列表中。post

         

非彙集索引結構

           

非彙集索引與彙集索引之間的顯著差異在於如下兩點:性能

  • 基礎表的數據行不按非彙集鍵的順序排序和存儲。
  • 非彙集索引的葉層是由索引頁而不是由數據頁組成。

問題:

  • 索引的結構到底分多少層?

咱們先看下B-樹,這種索引結構有一個重要的參數n,它決定了索引存儲頁的佈局,每一個存儲頁須要存放n個節點,以及n+1個指針。 這裏咱們來作個計算:好比咱們的索引是一個整形數字,4個字節,指針須要8個字節,這裏不考慮索引頁標頭信息的佔用,算下最大的n,公式: 4n+8(n+1)<=8*1024 ,這個值是680,即最大可存放680個鍵,再按B-樹充滿度來取75%等於510,根結點有510個,那麼它會有510*510個葉結點,這些葉結點會有510*510*510個指向最終記錄的指針。這個數據足以說明絕多數狀況下,只要三層就可以用。學習

  • 什麼是稠密索引?

索引中的鍵順序與數據文件中的排序順序相同,因此咱們的索引結構中,葉級均採用稿密索引。

  • 什麼是稀疏索引?

它只爲每一個存儲塊設計鍵-指針對,比稿密索引節約空間,出如今葉級之上的結構中。

  • 索引結構中會出現以下狀況嗎?

要想回答這個問題,就須要瞭解索引在維護過程當中對於B-樹的調整,SQL會經過必定的算法將B-樹的充滿度達到必定的平衡,這裏就會涉及的節點的拆分以及合併,因此通常狀況下不管對數據作怎樣的更新,也不會出現下圖中如此不平衡的狀況。

注:若是問重建索引的好處時,若是你回答是爲了平衡B-樹,那麼要謹慎回答。

   

總結

      數據存儲的基礎知識,索引結構對於咱們後續理解彙集索引以及非彙集索引都很是重要,也纔有可能快速準確的作出優化方案。

參考:http://technet.microsoft.com/zh-cn/library/ms180978(v=sql.105).aspx

相關文章
相關標籤/搜索