mysql索引實現 mysql索引底層實現原理

2021-10-18 11:52:42 字數 3222 閱讀 2150

一、定義

索引定義:索引(index)是幫助mysql高效獲取資料的資料結構。

本質:索引是資料結構。

二、b-tree

m階b-tree滿足以下條件:

1、每個節點至多可以擁有m棵子樹。

2、根節點,只有至少有2個節點(要麼極端情況,就是一棵樹就乙個根節點,單細胞生物,即是根,也是葉,也是樹)。

3、非根非葉的節點至少有的ceil(m/2)個子樹(ceil表示向上取整,如5階b樹,每個節點至少有3個子樹,也就是至少有3個叉)。

4、非葉節點中的資訊包括[n,a0,k1,a1,k2,a2,…,kn,an],,其中n表示該節點中儲存的關鍵字個數,k為關鍵字且ki

5、從根到葉子的每一條路徑都有相同的長度(葉子節點在相同的層)

b-tree特性:

1、關鍵字集合分布在整顆樹中;

2、任何乙個關鍵字出現且只出現在乙個節點中;

3、每個節點儲存date和key;

4、搜尋有可能在非葉子節點結束;

5、乙個節點中的key從左到右非遞減排列;

6、所有葉節點具有相同的深度,等於樹高h。

b-tree上查詢演算法的偽**如下:

三、b+tree

b+tree與b-tree的差異在於:

1、b+tree非葉子節點不儲存data,只儲存key;

2、所有的關鍵字全部儲存在葉子節點上;

3、每個葉子節點含有乙個指向相鄰葉子節點的指標,帶順序訪問指標的b+樹提高了區間查詢能力;

4、非葉子節點可以看成索引部分,節點中僅含有其子樹(根節點)中的最大(或最小)關鍵字;

四、b/b+樹索引的效能分析

依據:使用磁碟i/o次數評價索引結構的優劣

主存和磁碟以頁為單位交換資料,將乙個節點的大小設為等於乙個頁,因此每個節點只需一次i/o就可以完全載入。

根據b樹的定義,可知檢索一次最多需要訪問h個節點

漸進複雜度:o(h)=o(logdn)

dmax=floor(pagesize/(keysize+datasize+pointsize))

一般實際應用中,出度d是非常大的數字,通常超過100,因此h非常小(通常不超過3,3層可存大約一百萬資料)

b-tree中一次檢索最多需要h-1次i/o(根節點常駐記憶體)

b+tree內節點不含data域,因此出度d更大,則h更小,i/o次數少,效率更高,故b+tree更適合外存索引。

五、mysql索引實現

1、myisam引擎使用b+tree作為索引結構,葉節點的data域存放的是資料記錄的位址;

myisam主索引和輔助索引在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複;

2、innodb的資料檔案本身就是索引檔案,葉節點包含了完整的資料記錄,這種索引叫做聚集索引。

因為innodb的資料檔案本身要按主鍵聚集,所以innodb要求表必須有主鍵(myisam可以沒有),如果沒有顯式指定,則mysql系統會自動選擇乙個可以唯一標識資料記錄的列作為主鍵,如果不存在這種列,則mysql自動為innodb表生成乙個隱含字段作為主鍵。

innodb的輔助索引data域儲存相應記錄主鍵的值而不是位址;

輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄;

3、頁**問題

如果主鍵是單調遞增的,每條新記錄會順序插入到頁,當頁被插滿後,繼續插入到新的頁;

如果寫入是亂序的,innodb不得不頻繁地做頁**操作,以便為新的行分配空間。頁**會導致移動大量資料,一次插入最少需要修改三個頁而不是乙個頁。

如果頻繁的頁**,頁會變得稀疏並被不規則地填充,所以最終資料會有碎片。

六、總結

了解不同儲存引擎的索引實現方式對於正確使用和優化索引都非常有幫助

1、為什麼不建議使用過長的字段作為主鍵?

2、為什麼選擇自增字段作為主鍵?

3、為什麼常更新是字段不建議建立索引?

4、為什麼選擇區分度高的列作為索引?區分度的公式是count(distinct col)/count(*)

5、盡可能的使用覆蓋索引

七、優化limit分頁查詢

select * from table  where condition limit offset , rows ;

上述sql語句的實現機制是:

1、從「table」表中讀取offset+rows行記錄。

2、 拋棄前面的offset行記錄,返回後面的rows行記錄作為最終的結果。

覆蓋索引:

select  a.id, sid, parent_s_id from cashpool_account_relationship a join (select id from cashpool_account_relationship limit 1000000,10)b on a.id = b.id;

select  id, sid, parent_s_id from cashpool_account_relationship where id >=(select id from cashpool_account_relationship limit 1000000,1) limit 10;

八、q&a

1、innodb支援hash索引嗎?--馬欣

innodb是支援hash索引的,不過其支援的hash索引是自適應的,innodb儲存引擎會根據表的使用情況自動為表生成hash索引,不能人為干預是否在一張表中生成hash索引。

2、innodb主鍵索引的葉節點含完整的資料記錄,那主鍵索引檔案要比資料檔案大嗎?--徐財厚

1).在innodb 引擎中,主鍵索引中的葉子結點包含記錄資料,主鍵索引檔案即為資料檔案。

2).在 tables 表中統計的data_length資料為主鍵索引大小,index_length 為統計的這個表中所有輔助索引(二級索引)索引的大小。

mysql 雜湊索引 MySQL索引之雜湊索引

雜湊索引 hash index 建立在雜湊表的基礎上,它只對使用了索引中的每一列的精確查詢有用。對於每一行,儲存引擎計算出了被索引的雜湊碼 hash code 它是乙個較小的值,並且有可能和其他行的雜湊碼不同。它把雜湊碼儲存在索引中,並且儲存了乙個指向雜湊表中的每一行的指標。在mysql中,只有me...

mysql主鍵索引 MySQL索引之主鍵索引

在mysql裡,主鍵索引和輔助索引分別是什麼意思,有什麼區別?上次的分享我們介紹了聚集索引和非聚集索引的區別,本次我們繼續介紹主鍵索引和輔助索引的區別。1 主鍵索引 主鍵索引,簡稱主鍵,原文是primary key,由乙個或多個列組成,用於唯一性標識資料表中的某一條記錄。乙個表可以沒有主鍵,但最多只...

mysql聚集索引 MySQL索引之聚集索引介紹

在mysql裡,聚集索引和非聚集索引分別是什麼意思,有什麼區別?在mysql中,innodb引擎表是 聚集 索引組織表 clustered index organize table 而myisam引擎表則是堆組織表 heap organize table 也有人把聚集索引稱為聚簇索引。當然了,聚集索...