性能调优01Mysql索引底层原理

深入理解Mysql索引底层数据结构与算法

索引是什么

索引是帮助MySQL高效获取数据的排好序的数据结构

索引数据结构

二叉树

image-20211206223233336

缺点:

  • 索引树的高度 >= log2N + 1 高度可能较高,不可控
  • 索引步骤同样不可控,效率较低
  • 可能形成单向链表、索引效果底下

红黑树 (效率比二叉树高)

缺点:

  • 可能存在自旋,维护复杂
  • 高度不可控(千万级别数据,层数高)

image-20211206231403113

B-Tree

特点:

  • 叶节点具有相同的深度
  • 索引元素不重复
  • 节点从左到右递增

缺点:

  • 索引树的高度依旧不可控(因为mysql一般规定一个节点16kb,如果使用InnoDB存储引擎且是主建索引,则value存储的可能就是整个表数据,这会导致每个节点存储的接口个数较少,导致层数增大)

image-20211206231426218

Mysql的B+Tree(原B+Tree叶子结点是单向指针)

特点

  • 非叶子节点不存储data,只存储索引(叶子结点会冗余),因此可以放更多的索引
  • 叶子结点包含所有的索引字段
  • 叶子结点之间通过指针双向连接,提高区间访问的性能

image-20211206233052712

Mysql的Hash索引

维护索引列值的hash值和所在行的磁盘空间地址的关系表,可以快速查询出某个值所在行。

存在什么问题:

​ 不支持范围查询、模糊查询,排序,

优点:

单等值查询非常快

索引是怎么支撑千万级表的快速查找

使用B+树缩影,假设树的高度 h = 3,一个节点大小限制16k,主建索引,bigint = 8B,指针连接

=6B。总叶子结点 = (161024/14) * (161024/14) * 16 = 21902400

image-20211206233732916

InnoDB存储引擎索引实现

image-20211207232002050

MYSQL5.7

MYISAM存储引擎

​ .frm 表结构

​ .MYD 表数据

​ .MYI 表索引

MyISAM索引文件和数据文件是分离的(非聚集)

image-20211207235410948

INNODB存储引擎

​ .frm 表结构

​ .ibd 表数据

InnoDB的主建索引(聚簇索引)

image-20211207235514358

InnoDB的非主键索引(非聚簇索引)

​ 通过检索二级索引树查到对应主建,在检索主建索引树

image-20211207235521058

什么是聚簇索引和非聚簇索引

​ 聚簇索引:索引结构和表数据存储在一起的索引

​ 非聚簇索引:索引结构和表数据存储分开存储的索引

为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?

1、为什么推荐声明主建

答:B+树索引数据结构就是根据某个唯一索引组装而成的,就算不声明主建,Mysql也会自动生成一个唯一序列号作为key去构建整棵树

2、为什么推荐整形

答:如果用字符串,还得统一装换成ASCALL码进行比较大小,如果是整形则比较更加便捷
3、为什么推荐自增

答:B+树在逐步构建时都是某个节点满了才向右扩充,如果这个时候插入某一个值且这个值要放在已经满了的节点,则容易造成B+树频繁调整,维护麻烦。(自增插入的话,只会影响右下角区域的数据调整)

为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

1、节省存储空间,存在多个索引时,只有主键索引才包含所有数据,其他索引只冗余主建id,这样可以大大节约空间

2、如果多个索引都维护所有数据,那势必会有维护复杂,数据一致性问题,事倍功半。

联合索引的底层存储结构长什么样

image-20211207234827138

InnoDB 和 MyIsam 引擎的区别

特性 InnoDB MyISAM
事务支持 是 支持ACID
锁定级别 行级锁定 表级锁定
外键支持
崩溃恢复
全文本搜索 是(复杂) 是(简单)
读性能 一般 较好
写性能 一般 较差
适用场景 OLTP应用,事务处理 读密集型应用,全文本搜索