MySQL索引專題一 認識索引

關於這個專題

想寫MySQL的索引專題是源於以前本身在學習MySQL索引時痛苦的經歷,你在網上搜索關於MySQL的索引的文章,大可能是支離破碎,沒有系統性的對知識點的羅列堆砌,文章中會說明你要如何如何作,可是不多涉及去講爲何要這麼作,哪些不能作,很難對MySQL有一個系統性的認知,學習若是沒有系統性的話,就很難在實際的項目中靈活運用,出於此目的,本身就打算寫一個關於MySQL索引的專題系列,算是本身一個學習的總結,若是同時能幫到你那再好不過了。下面進入正題,咱們先來了解一下什麼是索引以及索引的類型。算法

認識索引

認識索引是什麼東西很是關鍵,一個很是恰當的比喻就是書的目錄頁書的正文內容之間的關係,爲了方便查找書中的內容,經過對內容創建索引造成目錄。所以,首先你要明白的一點就是,索引它也是一個文件,它是要佔據物理空間的。sql

好比對於MyISAM存儲引擎來講:
.frm後綴的文件存儲的是表結構。
.myd後綴的文件存儲的是表數據。
.myi後綴的文件存儲的就是索引文件。
以下圖所示:數據結構

對於InnoDB 存儲引擎來講:
.frm後綴的文件存儲的是表結構。
.ibd後綴的文件存放索引文件和數據(須要開啓innodb_file_per_table 參數)函數

以下圖所示:性能

圖片描述

所以,當你對一張表創建索引時,索引文件的大小也會改變,當你數據表中的數據由於增刪改變化時,索引文件也會變化的,只不過MySQL會自動維護索引,這個過程不須要你介入,這也是爲何不恰當的索引會影響MySQL性能的緣由。學習

總結:
1. 索引是按照特定的數據結構把數據表中的數據放在索引文件中,以便於快速查找;
2. 索引存在於磁盤中,會佔據物理空間。優化

索引的類型

上面說到,索引文件時按照不一樣的數據結構來存儲的,數據結構的不一樣也產生了不一樣的索引類型,常見的索引類型包括:搜索引擎

  1. B-Tree索引spa

  2. 哈希索引指針

  3. 空間數據索引(R-Tree)

  4. 全文索引
    下面作一一介紹:

1. B-Tree索引

B-Tree索引是最經常使用的一種索引,若是沒有指定特定的類型,那麼多半就是B-Tree索引,事實上,不少搜索引擎使用的是它的變種B+Tree,這是對B-Tree的一個優化,若是須要詳細瞭解,能夠參考數據結構方面的書籍,這裏不作詳細探討。如下統稱爲B-Tree索引。
絕大多數的存儲引擎,好比MyISAMInnoDB都支持這種索引,所以說它是應用最普遍,最經常使用的一種索引方式,可是不一樣的存儲引擎在具體實現時會稍有不一樣,好比MyISAM會使用前綴壓縮的方式對索引進行壓縮,InnoDB則不會。
下圖展現了B-Tree索引是如何存儲被索引的數據的:

說明:

  1. 左圖是一個包含三列的數據表,右圖則展現了數據是如何被索引的。

  2. 能夠看出B-Tree是對索引列是按照順序存儲的,每一個葉子節點指向被索引的數據,這也是B-Tree索引支持範圍查找數據的緣由。

2. 哈希索引

相比於B-Tree索引,哈希索引的實現就比較簡單了,它是基於哈希表來實現的,對於要索引的列,存儲引擎會計算出一一對應的哈希碼,而後把哈希碼存放在哈希表中做爲keyvalue值是指向該行數據的指針。
下圖是簡單的原理展現:

說明:

  1. 左邊紫色圖表示一個二列的數據表。

  2. 中間表示對fname列進行哈希索引,計算出哈希值。

  3. 右邊綠色圖表示把生成的哈希值存放於哈希表中。

當咱們執行如下查詢時:

select * from testTable where fname = "mary";

MySQL會首先計算查詢條件mary的哈希值,而後到哈希表中去找該哈希值,若是找到了根據對應的指針也就找到了須要尋找的數據行。

哈希表的優點與限制:

  • 優點:

    1. 只需比對哈希值,所以速度很是快,性能優點明顯;

  • 限制:

    1. 不支持任何範圍查詢,好比where price > 150,由於是基於哈希計算,支持等值比較。

    2. 哈希表是無序存儲的,所以索引數據沒法用於排序。

    3. 主流存儲引擎不支持該類型,好比MyISAMInnoDB。哈希索引只有Memory, NDB兩種引擎支持。

所以,哈希索引雖然速度快,但其實使用很受限,只適用於某些特殊的場合。

3. 空間數據索引(R-Tree)

空間索引可用於地理數據存儲,它須要GIS相關函數的支持,因爲MySQLGIS支持並不完善,因此該索引方式在MySQL中不多有人使用。

4. 全文索引

全文索引主要用於海量數據的搜索,好比淘寶或者京東對商品的搜索,你不可能使用like進行模糊匹配吧,MySQL5.6開始支持InnoDB引擎的全文索引,功能沒有專業的搜索引擎好比SphinxSolr豐富,若是你的需求比較簡單,能夠嘗試一下MySQL的全文索引,不然建議使用專業的搜索引擎。

總結:
1. B-Tree索引使用最普遍,主流引擎都支持。
2. 哈希索引性能高,適用於特殊場合。
3. R-Tree不經常使用。
4. 全文索引適用於海量數據的關鍵字模糊搜索。


索引和存儲引擎之間的關係

上面講述了索引有不一樣的類型,存儲引擎也有不一樣的類型,那麼索引和存儲引擎之間有什麼關係呢?
首先你須要知道,在MySQL中,索引是在存儲引擎中實現的,並非全部的存儲引擎都支持全部的索引類型,好比哈希索引,MyISAMInnoDB是不支持的;一樣,即便對於同一類型的索引,不一樣的存儲引擎實現的方式也多是不一樣的,好比MyISAMInnoDBB-Tree索引,具體的實現是有差異的。

總結:
1. 不一樣的存儲引擎可能支持不一樣的索引類型;
2. 不一樣的存儲引擎對同一中索引類型可能有不一樣的實現方式。


B-Tree索引與惟一索引,主鍵索引,普通索引的關係

最開始對B-Tree索引與惟一索引,主鍵索引,普通索引這幾種索引的關係很模糊,網上也沒搜索到相關的資料,覺得他們的關係是並列的,其實並非,B-Tree只是底層的算法實現,惟一索引,主鍵索引,普通索引都是基於B-Tree索引算法的,只不過又有各自的特色。
經過下圖也可看出這種關係:

至於惟一索引,主鍵索引,普通索引之間的區別,下面補充一下:

  • 主鍵索引:數據列不容許重複,不容許爲NULL.一個表只能有一個主鍵。

  • 惟一索引:數據列不容許重複,容許爲NULL值,一個表容許多個列建立惟一索引。

  • 普通索引:基本的索引類型,沒有惟一性的限制,容許爲NULL值。


總結:

這篇文章先說到這裏,目的主要是對MySQL的索引有個概念上的認識,以及瞭解索引的類型,索引和存儲引擎之間的關係,本專題會繼續更新,繼續對MySQL索引知識逐漸展開,若是你感興趣的話能夠關注該專欄,以及順便動動手指關注一下我(^_^),但願本文對你有所幫助。

相關文章
相關標籤/搜索