1. 程式人生 > >淺談數據庫索引的結構設計與優化

淺談數據庫索引的結構設計與優化

子句 項目 結果 使用 enter tex 設有 簡單的 相同

淺談數據庫索引的結構設計與優化

一. 了解數據庫索引的必要性

  對於稍微數據量大一點的表,如果不適用索引,那麽性能效率都會很低;如果繞開了索引,直接進行分區分表,數據庫集群讀寫分離來解決性能問題的話,那麽未免也太小題大做了。

  對於大多數中小型系統,索引能夠幫你解決90%的性能問題,所以索引是解決關系型數據庫非常有利的武器。

二. 表和索引結構

  1.索引頁和表頁

    表和索引都是存在頁中。頁的大小一般是4KB.頁的大小僅僅決定了一個頁能存儲多少個索引行,表行。

  2.索引行

    索引行是很有用的一個概念對於訪問路徑的時候。索引行的概念可以通過下圖來了解:

      技術分享圖片

    每一個頁上包含了很多索引行,每個索引行裏存儲著索引條目和指向下一層的頁,這種數據結構為B-tree結構。

  3.緩沖池和磁盤I/O

    我們可以使用內存的緩沖池來減小到磁盤的訪問。這一策略對sql性能表現至關重要。下圖展示了磁盤讀取到緩沖區的巨大成本:

  

      技術分享圖片

    當我們需要某一頁的一行數據時,和需要這一頁的數據時,所花費的時間是相等的。可以通過執行:show global status like ‘innodb%read%‘;來判斷緩存命中的情況,具體的參數可以自行在網上查找:

      技術分享圖片

      可以算出來緩存命中率為=260850/(64+260850+1927)=99.24%,是很高的命中率了。

  4.硬件特性

    硬盤磁盤的圖可以用下圖簡單表示:

      技術分享圖片

    我們的數據庫表裏的數據就保存在磁盤上,如果要讀取數據,就要磚頭磁盤,用磁頭和磁盤的磁力來改變狀態,來讀取數據,所以,我們應該盡量少的轉動磁盤,來優化數據庫性能。

  

三.SQL處理過程

  我們現在先討論基礎的處理過程,先來談談處理過程的一些基本概念。

  1.關鍵字(謂詞)

  where子句由一個或者多個謂詞組成,比如說:

    技術分享圖片

  

  那麽這個就有一個組合謂詞,組合謂詞是索引設計的主要入手點。

  2.過濾因子

  過濾因子是描述謂詞的選擇性,它主要依賴於列值的分布情況。它是一個計算值,公式為:

        技術分享圖片

  用來計算謂詞結果集的返回大小估算。

  3.物化結果集

  是執行數據庫訪問來構建結果集。最好的情況下,是從數據庫緩沖池返回一條記錄,最壞的情況就是訪問大量的磁盤讀取數據。

  物化結果集有2種方式:

            1.一次FETCH物化返回一條數據

            2.提前物化

四.為SELECT語句創建理想索引

  1.三星索引

  三星索引是指一條sql所能達到索引的最優設計。

  第一顆星:

    如果與一個查詢相關的索引行是相鄰的,那麽這個索引就為第一顆星。

  第二顆星:

    如果索引行的順序與查詢語句一致,則為第二顆星。

  第三顆星:

    查詢的數據為索引的信息,不需要額外的磁盤隨機讀。這一顆星能大大改善性能。

  假設有一條sql語句如下所示:

    技術分享圖片

  如果要滿足一星索引:索引的順序可以是LNAME,CITY或者CITY,LNAME

  如果要滿足第二星索引:FNAME加在LNAME,CITY或者CITY,LNAME後面

  如果要滿足第三索引:CNO也要在索引裏面

  那麽組合起來得三星索引就是:LNAME,CITY,FNAME,CNO或者CITY,LNAME,FNAME,CNO

五.前瞻性索引

  1.發現不合適的索引

  有兩種基本的方法來發現不合適的索引:

            1.基本問題法(BQ)

            2.快速上線評估法(QUBE)

  在這裏我僅僅討論一下快速上線評估法(QUBE)

  

  2.快速上線評估法(QUBE)

   QUBE是悲觀上限,它的目的是在早期發現程序設計的缺陷,並且及時更改。QUBE忽略了排隊時間,鎖競爭時間等,把問題單一化來評估sql的性能問題。

   下圖就是QUBE計算評估sql時間公式:

              技術分享圖片

  可以發現,TR和TS存在巨大的時間差距,隨機訪問會消耗大量的時間,那麽來說說隨機和順序訪問。

  隨機訪問:

    先說一說磁盤讀和訪問的區別。讀是讀取一頁的信息,訪問時訪問一行的信息。所以單次隨機訪問的時間與一次磁盤隨機讀取的時間相同,都是10ms。

  順序訪問:

    一次順序讀是指物理上讀取連續的下一行,這一行要麽在同一頁中,要麽在下一頁中,估算出來時間是0.01ms。

  FETCH:

    是FETCH調用次數來確定被接收行的數量。F的時間數量級要比TS大一級,但是要比TR小2級。

  下面給出一個簡單的事例來說明QUBE計算方法:

      技術分享圖片

  那麽可以根據上面的公式得到:

      技術分享圖片

  QUBE算法其實可以多結合自己的項目事例來計算判斷一下,因為這個公式是很多年前的了,現在磁盤讀寫能力肯定有了顯著提升,但是判斷sql性能的方式是一致的。

      

淺談數據庫索引的結構設計與優化