1. 程式人生 > >BTREE索引和HASH索引,聚集索引和非聚集索引

BTREE索引和HASH索引,聚集索引和非聚集索引

https://www.jianshu.com/p/76530afa13cb

https://blog.csdn.net/yifanSJ/article/details/79220044

BTREE索引和HASH索引

1、不同引擎的預設索引

不同的引擎對於索引有不同的支援:Innodb和MyISAM預設的索引是Btree索引;而Mermory預設的索引是Hash索引。

 

2、Hash索引

所謂Hash索引,當我們要給某張表某列增加索引時,將這張表的這一列進行雜湊演算法計算,得到雜湊值,排序在雜湊陣列上。所以Hash索引可以一次定位,其效率很高,而Btree索引需要經過多次的磁碟IO,但是innodb和myisam之所以沒有采用它,是因為它存在著好多缺點:

(1)Hash 索引僅僅能滿足"=","IN"和"<=>"查詢,不能使用範圍查詢。

由於 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、Btree索引

至於Btree索引,它是以B+樹為儲存結構實現的。

但是Btree索引的儲存結構在Innodb和MyISAM中有很大區別。

MyISAM中資料檔案和索引檔案是分開的,索引檔案儲存的是資料在資料檔案的地址。

Innodb的索引檔案就是資料檔案,相當於是重新建立了一個有索引順序的資料檔案。另外在Innodb中,輔助索引的葉子節點儲存的是主鍵資訊,然後根據主鍵資訊到主索引中定位表中的資料。因此主鍵不宜用過長的欄位,在Innodb中儘量使用自增的主鍵,這樣每次增加資料時只需要在後面新增即可,非單調的主鍵在插入時會需要維持B+tree特性而進行分裂調整,重新建立索引,十分低效。

因此MyISAM的索引方式也稱為非聚集,Innodb的索引方式稱為聚集索引。

 

4、下面需要說明一下聚集索引和非聚集索引的概念

聚集索引

1.當你定義一個主鍵時,InnnodDB儲存引擎則把它當做聚集索引

2.如果你沒有定義一個主鍵,則InnoDB定位到第一個唯一索引,且該索引的所有列值均非空的,則將其當做聚集索引。

3如果表沒有主鍵或合適的唯一索引INNODB會產生一個隱藏的行ID值6位元組的行ID聚集索引,

補充:由於實際的資料頁只能按照一顆B+樹進行排序,因此每張表只能有一個聚集索引,聚集索引對於主鍵的排序和範圍查詢非常有利,

非聚集索引

一個表中的所有索引除了聚集索引,其他的都是非聚集索引(secondary index)

輔助索引,其葉子節點並不包含行記錄的全部資料,葉子結點除了包含鍵值以外,每個葉子結點中的索引行還包含了一個書籤,該書籤用來告訴儲存引擎可以在哪找到相應的資料行,由於innodb引擎表是索引組織表,因此innodb儲存引擎的輔助索引的書籤就是相應行資料的聚集索引鍵,即主鍵資訊。

 

5、 Btree索引中的最左匹配原則

Btree是按照從左到右的順序來建立搜尋樹。比如索引是(name,age,sex),相當於是建立了單列索引(name)、組合索引(name,age)和組合索引(name,age,sex)。假如搜尋age=? and sex =?或者name=? and sex=?的話都是利用不到這個索引的。

 

6、 索引的index型別和ref型別

http://blog.csdn.net/qq_24690761/article/details/52787897

在使用EXPLAIN分析查詢語句的時候會發現type有index型別和ref型別。

index型別表示是全表掃描該索引。只要是索引,或者某個複合索引的一部分,mysql都可能會採用index型別的方式掃描。但是因為是全表從頭到尾掃描,因此效率並不高。

ref型別表示能夠利用到建立好的索引,快速定位到索引的位置,而不是全表掃描。要利用到這種索引就要符合最左匹配原則。

 

7、建立索引的規則

1、利用最左字首:Mysql會一直向右查詢直到遇到範圍操作(>,<,like、between)就停止匹配。比如a=1 and b=2 and c>3 and d=6;此時如果建立了(a,b,c,d)索引,那麼後面的d索引是完全沒有用到,當換成了(a,b,d,c)就可以用到。

2、不能過度索引:在修改表內容的時候,索引必須更新或者重構,所以索引過多時,會消耗更多的時間。

3、儘量擴充套件索引而不要新建索引。

4、最適合的索引的列是出現在where子句中的列或連線子句中指定的列。

5、不同值較少的列不必要建立索引(性別)。