【金三銀四】深刻理解Mysql索引底層數據結構解密

【MySql系列】文章導航

【金三銀四】深刻理解MySql索引底層數據結構解密 juejin.im/post/5e0d7b…html

【金三銀四】MySql執行計劃EXPLAIN詳解 juejin.im/post/5e12e4…java

【金三銀四】MySql執行計劃EXPLAIN最佳實踐 juejin.im/post/5e12e4…mysql

【金三銀四】MySql索引優化實戰 juejin.im/post/5e12e5…面試

開始

2B哥從Mysql面試題開始提及吧。算法

案例sql

CREATE TABLE `employees` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名',
  `age` int(11) NOT NULL DEFAULT '0' COMMENT '年齡',
  `position` varchar(20) NOT NULL DEFAULT '' COMMENT '職位',
  `hire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入職時間',
  PRIMARY KEY (`id`),
  KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='員工記錄表';
INSERT INTO employees(name,age,position,hire_time) VALUES('LiLei',22,'manager',NOW());
INSERT INTO employees(name,age,position,hire_time) VALUES('HanMeimei', 23,'dev',NOW());
INSERT INTO employees(name,age,position,hire_time) VALUES('Lucy',23,'dev',NOW());
複製代碼

分析如下幾條sql的索引使用狀況bash

SELECT * FROM employees WHERE name= 'LiLei';
SELECT * FROM employees WHERE name= 'LiLei' AND age = 22 AND position ='manager';
SELECT * FROM employees WHERE age = 22 AND position = 'manager';
SELECT * FROM employees WHERE name= 'LiLei' AND age > 22 AND position = 'manager';
SELECT * FROM employees WHERE name != 'LiLei';
複製代碼

圖片

Mysql的索引分析

MySQL官方對索引的定義爲:索引(Index)是幫助MySQL高效獲取數據的數據結構。數據結構

索引的本質:索引是數據結構,並且是實現了高級查找算法的數據結構post

索引通常以文件形式存儲在磁盤上,索引檢索須要磁盤I/O操做性能

磁盤存取原理

  • 尋道時間(速度慢,費時)

  • 旋轉時間(速度較快) 預讀:長度爲頁的整倍數( 主存和磁盤以頁爲單位交換數據,一頁4K)

    圖片

什麼是索引

索引是用來快速檢索出具備特定值的記錄。 MySQL官方對索引的定義爲:索引(Index)是幫助MySQL高效獲取數據的數據結構

論索引重要性

在好比咱們生活中去圖書館找書,咱們要找到圖中的葵花寶典實在是太難了(從一樓到三樓所有都要看一遍書名)

但也有這種一眼去能夠找到的狀況,如圖找PHP這本書(Java是世界上最好的語言)所示:

根據找書的規則咱們能夠得出兩個結論:

一、書的數量

二、書的位置

這兩個條件決定了找到這本書的速度。那跟咱們索引有什麼關係了?看這個圖

索引重要嗎?如圖所示,沒有用到索引和用到索引速度對比。

索引的結構

  • 二叉樹
  • 紅黑樹
  • HASH
  • BTREE

更多數據結構動畫演示:數據結構教學網站

圖片

索引底層數據結構與算法

Hash索引

若是是等值查詢,哈希索引明顯有絕對優點, 前提:鍵值惟一

哈希索引沒辦法完成範圍查詢檢索

哈希索引也沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢

哈希索引也不支持多列聯合索引的

在有大量重複鍵值狀況下,哈希索引的效率也最左前綴原則是極低的,由於存在哈希碰撞問題

圖片

B-Tree

  • 度(Degree)-節點的數據存儲個數
  • 葉子節點具備相同的深度
  • 葉子節點的指針爲空
  • 節點中的數據key從左到右遞增排列

圖片

B+Tree

  • 非葉子節點不存儲data,只存儲key,能夠增大度
  • 葉子節點不存儲指針
  • 順序訪問指針,提升區間訪問的性能

圖片

MyISAM索引實現(非彙集)

MyISAM索引文件和數據文件是分離的

圖片

圖片

InnoDB索引實現(彙集)

  • 數據文件自己就是索引文件
  • 表數據文件自己就是按B+Tree組成的一個索引結構文件
  • 彙集索引-葉節點包含了完整的數據記錄
  • 爲何InnoDB表要求有主鍵,而且推薦使用整型的自增主鍵?

沒有主鍵:dev.mysql.com/doc/refman/…

  • 爲何非主鍵索引結構葉子節點存儲的是主鍵值?(一致性和節省存儲空間)

圖片

圖片

福利

贈送一份mysql知識圖譜,高清版本關注公衆號:java2b

相關文章
相關標籤/搜索