想寫MySQL
的索引專題是源於以前本身在學習MySQL
索引時痛苦的經歷,你在網上搜索關於MySQL
的索引的文章,大可能是支離破碎,沒有系統性的對知識點的羅列堆砌,文章中會說明你要如何如何作,可是不多涉及去講爲何要這麼作,哪些不能作,很難對MySQL
有一個系統性的認知,學習若是沒有系統性的話,就很難在實際的項目中靈活運用,出於此目的,本身就打算寫一個關於MySQL
索引的專題系列,算是本身一個學習的總結,若是同時能幫到你那再好不過了。下面進入正題,咱們先來了解一下什麼是索引以及索引的類型。算法
認識索引是什麼東西很是關鍵,一個很是恰當的比喻就是書的目錄頁
與書的正文內容
之間的關係,爲了方便查找書中的內容,經過對內容創建索引
造成目錄
。所以,首先你要明白的一點就是,索引
它也是一個文件,它是要佔據物理空間的。sql
好比對於MyISAM
存儲引擎來講:.frm
後綴的文件存儲的是表結構。.myd
後綴的文件存儲的是表數據。.myi
後綴的文件存儲的就是索引文件。
以下圖所示:數據結構
對於InnoDB
存儲引擎來講:.frm
後綴的文件存儲的是表結構。.ibd
後綴的文件存放索引文件和數據(須要開啓innodb_file_per_table
參數)函數
以下圖所示:性能
所以,當你對一張表創建索引時,索引文件的大小也會改變,當你數據表中的數據由於增刪改
變化時,索引文件也會變化的,只不過MySQL
會自動維護索引,這個過程不須要你介入,這也是爲何不恰當的索引會影響MySQL
性能的緣由。學習
總結:
1. 索引是按照特定的數據結構
把數據表中的數據放在索引文件
中,以便於快速查找;
2. 索引存在於磁盤中,會佔據物理空間。優化
上面說到,索引文件時按照不一樣的數據結構來存儲的,數據結構的不一樣也產生了不一樣的索引類型,常見的索引類型包括:搜索引擎
B-Tree
索引spa
哈希
索引指針
空間數據索引(R-Tree
)
全文索引
下面作一一介紹:
B-Tree
索引B-Tree
索引是最經常使用的一種索引,若是沒有指定特定的類型,那麼多半就是B-Tree
索引,事實上,不少搜索引擎使用的是它的變種B+Tree
,這是對B-Tree
的一個優化,若是須要詳細瞭解,能夠參考數據結構方面的書籍,這裏不作詳細探討。如下統稱爲B-Tree
索引。
絕大多數的存儲引擎,好比MyISAM
和InnoDB
都支持這種索引,所以說它是應用最普遍,最經常使用的一種索引方式,可是不一樣的存儲引擎在具體實現時會稍有不一樣,好比MyISAM
會使用前綴壓縮的方式對索引進行壓縮,InnoDB
則不會。
下圖展現了B-Tree
索引是如何存儲被索引的數據的:
說明:
左圖是一個包含三列的數據表,右圖則展現了數據是如何被索引的。
能夠看出
B-Tree
是對索引列是按照順序存儲的,每一個葉子節點指向被索引的數據,這也是B-Tree
索引支持範圍查找數據的緣由。
相比於B-Tree
索引,哈希索引的實現就比較簡單了,它是基於哈希表來實現的,對於要索引的列,存儲引擎會計算出一一對應的哈希碼
,而後把哈希碼存放在哈希表中做爲key
,value
值是指向該行數據的指針。
下圖是簡單的原理展現:
說明:
左邊紫色圖表示一個二列的數據表。
中間表示對
fname
列進行哈希索引,計算出哈希值。右邊綠色圖表示把生成的哈希值存放於哈希表中。
當咱們執行如下查詢時:
select * from testTable where fname = "mary";
MySQL
會首先計算查詢條件mary
的哈希值,而後到哈希表中去找該哈希值,若是找到了根據對應的指針也就找到了須要尋找的數據行。
哈希表的優點與限制:
優點:
只需比對哈希值,所以速度很是快,性能優點明顯;
限制:
不支持任何範圍查詢,好比where price > 150
,由於是基於哈希計算,支持等值比較。
哈希表是無序存儲的,所以索引數據沒法用於排序。
主流存儲引擎不支持該類型,好比MyISAM
和InnoDB
。哈希索引只有Memory, NDB兩種引擎支持。
所以,哈希索引雖然速度快,但其實使用很受限,只適用於某些特殊的場合。
R-Tree
)空間索引可用於地理數據存儲,它須要GIS
相關函數的支持,因爲MySQL
的GIS
支持並不完善,因此該索引方式在MySQL
中不多有人使用。
全文索引主要用於海量數據的搜索,好比淘寶或者京東對商品的搜索,你不可能使用like
進行模糊匹配吧,MySQL
從5.6
開始支持InnoDB
引擎的全文索引,功能沒有專業的搜索引擎好比Sphinx
或Solr
豐富,若是你的需求比較簡單,能夠嘗試一下MySQL
的全文索引,不然建議使用專業的搜索引擎。
總結:
1. B-Tree索引使用最普遍,主流引擎都支持。
2. 哈希索引性能高,適用於特殊場合。
3. R-Tree
不經常使用。
4. 全文索引適用於海量數據的關鍵字模糊搜索。
上面講述了索引有不一樣的類型,存儲引擎也有不一樣的類型,那麼索引和存儲引擎之間有什麼關係呢?
首先你須要知道,在MySQL
中,索引是在存儲引擎中實現的,並非全部的存儲引擎都支持全部的索引類型,好比哈希索引,MyISAM
和InnoDB
是不支持的;一樣,即便對於同一類型的索引,不一樣的存儲引擎實現的方式也多是不一樣的,好比MyISAM
和InnoDB
對B-Tree
索引,具體的實現是有差異的。
總結:
1. 不一樣的存儲引擎可能支持不一樣的索引類型;
2. 不一樣的存儲引擎對同一中索引類型可能有不一樣的實現方式。
B-Tree
索引與惟一索引,主鍵索引,普通索引的關係最開始對B-Tree
索引與惟一索引,主鍵索引,普通索引這幾種索引的關係很模糊,網上也沒搜索到相關的資料,覺得他們的關係是並列的,其實並非,B-Tree
只是底層的算法實現,惟一索引,主鍵索引,普通索引都是基於B-Tree
索引算法的,只不過又有各自的特色。
經過下圖也可看出這種關係:
至於惟一索引,主鍵索引,普通索引之間的區別,下面補充一下:
主鍵索引:數據列不容許重複,不容許爲NULL
.一個表只能有一個主鍵。
惟一索引:數據列不容許重複,容許爲NULL
值,一個表容許多個列建立惟一索引。
普通索引:基本的索引類型,沒有惟一性的限制,容許爲NULL
值。
這篇文章先說到這裏,目的主要是對MySQL
的索引有個概念上的認識,以及瞭解索引的類型,索引和存儲引擎之間的關係,本專題會繼續更新,繼續對MySQL
索引知識逐漸展開,若是你感興趣的話能夠關注該專欄,以及順便動動手指關注一下我(^_^),但願本文對你有所幫助。