在MySQL 中,主要有四種類型的索引,分別為:B-Tree 索引,Hash 索引,Fulltext 索引和RTree索引 1、B-Tree 索引 B-Tree 索引是MySQL 資料庫中使用最為頻繁的索引類型,除了Archive 存儲引擎之外的其他所有的存儲引擎都支持B-Tree 索引。不僅僅在M ...
在MySQL 中,主要有四種類型的索引,分別為:B-Tree 索引,Hash 索引,Fulltext 索引和RTree索引 1、B-Tree 索引 B-Tree 索引是MySQL 資料庫中使用最為頻繁的索引類型,除了Archive 存儲引擎之外的其他所有的存儲引擎都支持B-Tree 索引。不僅僅在MySQL 中是如此,實際上在其他的很多資料庫管理系統中B-Tree 索引也同樣是作為最主要的索引類型,這主要是因為B-Tree 索引的存儲結構在資料庫的數據檢索中有非常優異的表現。 一般來說,MySQL 中的B-Tree 索引的物理文件大多都是以Balance Tree 的結構來存儲的,也就是所有實際需要的數據都存放於Tree 的Leaf Node,而且到任何一個Leaf Node 的最短路徑的長度都是完全相同的,所以我們大家都稱之為B-Tree 索引當然,可能各種資料庫(或MySQL 的各種存儲引擎)在存放自己的B-Tree 索引的時候會對存儲結構稍作改造。如Innodb 存儲引擎的B-Tree 索引實際使用的存儲結構實際上是B+Tree,也就是在B-Tree 數據結構的基礎上做了很小的改造,在每一個Leaf Node 上面出了存放索引鍵的相關信息之外,還存儲了指向與該Leaf Node 相鄰的後一個Leaf Node 的指針信息,這主要是為了加快檢索多個相鄰Leaf Node 的效率考慮。 在Innodb 存儲引擎中,存在兩種不同形式的索引,一種是Cluster 形式的主鍵索引(PrimaryKey),另外一種則是和其他存儲引擎(如MyISAM 存儲引擎)存放形式基本相同的普通B-Tree 索引,這種索引在Innodb 存儲引擎中被稱為Secondary Index。下麵我們通過圖示來針對這兩種索引的存放形式做一個比較。 圖示中左邊為Clustered 形式存放的Primary Key,右側則為普通的B-Tree 索引。兩種索引在Root Node 和Branch Nodes 方面都還是完全一樣的。而Leaf Nodes 就出現差異了。在Primary Key中,Leaf Nodes 存放的是表的實際數據,不僅僅包括主鍵欄位的數據,還包括其他欄位的數據,整個數據以主鍵值有序的排列。而Secondary Index 則和其他普通的B-Tree 索引沒有太大的差異,只是在Leaf Nodes 出了存放索引鍵的相關信息外,還存放了Innodb 的主鍵值。 所以,在Innodb 中如果通過主鍵來訪問數據效率是非常高的,而如果是通過Secondary Index 來訪問數據的話,Innodb 首先通過Secondary Index 的相關信息,通過相應的索引鍵檢索到Leaf Node之後,需要再通過Leaf Node 中存放的主鍵值再通過主鍵索引來獲取相應的數據行。 MyISAM 存儲引擎的主鍵索引和非主鍵索引差別很小,只不過是主鍵索引的索引鍵是一個唯一且非空的鍵而已。而且MyISAM 存儲引擎的索引和Innodb 的Secondary Index 的存儲結構也基本相同,主要的區別隻是MyISAM 存儲引擎在Leaf Nodes 上面出了存放索引鍵信息之外,再存放能直接定位到MyISAM 數據文件中相應的數據行的信息(如Row Number),但並不會存放主鍵的鍵值信息。 2、Hash 索引 Hash 索引在MySQL 中使用的並不是很多,目前主要是Memory 存儲引擎使用,而且在Memory 存儲引擎中將Hash 索引作為預設的索引類型。所謂Hash 索引,實際上就是通過一定的Hash 演算法,將需要索引的鍵值進行Hash 運算,然後將得到的Hash 值存入一個Hash 表中。然後每次需要檢索的時候,都會將檢索條件進行相同演算法的Hash 運算,然後再和Hash 表中的Hash 值進行比較並得出相應的信息。 在Memory 存儲引擎中,MySQL 還支持非唯一的Hash 索引。可能很多人會比較驚訝,如果是非唯一的Hash 索引,那相同的值該如何處理呢?在Memory 存儲引擎的Hash 索引中,如果遇到非唯一值,存儲引擎會將他們鏈接到同一個hash 鍵值下以一個鏈表的形式存在,然後在取得實際鍵值的時候時候再過濾不符合的鍵。 由於Hash 索引結構的特殊性,其檢索效率非常的高,索引的檢索可以一次定位,而不需要像BTree索引需要從根節點再到枝節點最後才能訪問到頁節點這樣多次IO 訪問,所以Hash 索引的效率要遠高於B-Tree 索引。 可能很多人又會有疑問了,既然Hash 索引的效率要比B-Tree 高很多,為什麼大家不都用Hash索引而還要使用B-Tree 索引呢?任何事物都是有兩面性的,,Hash 索引也一樣,雖然Hash 索引檢索效率非常之高,但是Hash 索引本身由於其實的特殊性也帶來了很多限制和弊端,主要有以下這些: 1). Hash 索引僅僅只能滿足“=”,“IN”和“<=>”查詢,不能使用範圍查詢; 由於Hash 索引所比較的是進行Hash 運算之後的Hash 值,所以Hash 索引只能用於等值的過濾,而不能用於基於範圍的過濾,因為經過相應的Hash 演算法處理之後的Hash 值的大小關係,並不能保證還和Hash 運算之前完全一樣。 2). Hash 索引無法被利用來避免數據的排序操作; 由於Hash 索引中存放的是經過Hash 計算之後的Hash 值,而且Hash 值的大小關係並不一定和Hash 運算前的鍵值的完全一樣,所以資料庫無法利用索引的數據來避免任何和排序運算; 3). Hash 索引不能利用部分索引鍵查詢; 對於組合索引,Hash 索引在計算Hash 值的時候是組合索引鍵合併之後再一起計算Hash 值, 而不是單獨計算Hash 值,所以當我們通過組合索引的前面一個或幾個索引鍵進行查詢的時 候,Hash 索引也無法被利用到; 4). Hash 索引在任何時候都不能避免表掃面; 前面我們已經知道,Hash 索引是將索引鍵通過Hash 運算之後,將Hash 運算結果的Hash 值 和所對應的行指針信息存放於一個Hash 表中,而且由於存在不同索引鍵存在相同Hash 值的可能,所以即使我們僅僅取滿足某個Hash 鍵值的數據的記錄條數,都無法直接從Hash 索引中直接完成查詢,還是要通過訪問表中的實際數據進行相應的比較而得到相應的結果。 5). Hash 索引遇到大量Hash 值相等的情況後性能並不一定就會比B-Tree 索引高; 對於選擇性比較低的索引鍵,如果我們創建Hash 索引,那麼我們將會存在大量記錄指針信息存與同一個Hash 值相關連。這樣要定位某一條記錄的時候就會非常的麻煩,可能會浪費非常多次表數據的訪問,而造成整體性能的地下。 3、Full-text 索引 Full-text 索引也就是我們常說的全文索引,目前在MySQL 中僅有MyISAM 存儲引擎支持,而且也並不是所有的數據類型都支持全文索引。目前來說,僅有CHAR,VARCHAR 和TEXT 這三種數據類型的列可以建Full-text 索引。 一般來說,Fulltext 索引主要用來替代效率低下的LIKE '%***%' 操作。實際上,Full-text 索引並不只是能簡單的替代傳統的全模糊LIKE 操作,而且能通過多欄位組合的Full-text 索引一次全模糊匹配多個欄位。 Full-text 索引和普通的B-Tree 索引的實現區別較大,雖然他同樣是以B-Tree 形式來存放索引數據,但是他並不是通過欄位內容的完整匹配,而是通過特定的演算法,將欄位數據進行分隔後再進行的索引。一般來說MySQL 系統會按照四個位元組來分隔。在整個Full-text 索引中,存儲內容被分為兩部分,一部分是分隔前的索引字元串數據集合,另一部分是分隔後的詞(或者片語)的索引信息。所以,Full-text 索引中,真正在B-Tree 索引細細中的並不是我們表中的原始數據,而是分詞之後的索引數據。在B-Tree 索引的節點信息中,存放了各個分隔後的詞信息,以及指向包含該詞的分隔前字元串信息在索引數據集合中的位置信息。 Full-text 索引不僅僅能實現模糊匹配查找,在實現了基於自然語言的的匹配度查找。當然,這個匹配讀到底有多準確就需要讀者朋友去自行驗證了。Full-text 通過一些特定的語法信息,針對自然語言做了各種相應規則的匹配,最後給出非負的匹配值。 此外,有一點是需要大家註意的,MySQL 目前的Full-text 索引在中文支持方面還不太好,需要藉助第三方的補丁或者插件來完成。而且Full-text 的創建所消耗的資源也是比較大的,所以在應用於實際生產環境之前還是儘量做好評估。 4、R-Tree 索引 R-Tree 索引可能是我們在其他資料庫中很少見到的一種索引類型,主要用來解決空間數據檢索的問題。 在MySQL 中,支持一種用來存放空間信息的數據類型GEOMETRY,且基於OpenGIS 規範。在MySQL5.0.16 之前的版本中,僅僅MyISAM 存儲引擎支持該數據類型,但是從MySQL5.0.16 版本開始,BDB,Innodb,NDBCluster 和Archive 存儲引擎也開始支持該數據類型。當然,雖然多種存儲引擎都開始支持GEOMETRY 數據類型,但是僅僅之後MyISAM 存儲引擎支持R-Tree 索引。 在MySQL 中採用了具有二次分裂特性的R-Tree 來索引空間數據信息,然後通過幾何對象(MRB)信息來創建索引。 雖然僅僅只有MyISAM 存儲引擎支持空間索引(R-Tree Index),但是如果我們是精確的等值匹配,創建在空間數據上面的B-Tree 索引同樣可以起到優化檢索的效果,空間索引的主要優勢在於當我們使用範圍查找的時候,可以利用到R-Tree 索引,而這時候,B-Tree 索引就無能為力了。