这是我参与「第五届青训营 」伴学笔记创作活动的第 15天
MySQL 索引
背景
-
全表扫描,在InnoDB中从数据引擎中一次读取16kb到内存,那么对于一条查询SQL,磁盘IO的次数和数据总量成比例,即全表扫描的开销会随着数据量增长而越来越大
-
构建索引 高效
索引分类
可以按照四个角度来分类索引。
- 按「数据结构」分类:B+tree索引、Hash索引、Full-text索引。
- 按「物理存储」分类:聚簇索引(主键索引)、二级索引(辅助索引)。
- 按「字段特性」分类:主键索引、唯一索引、普通索引、前缀索引。
- 按「字段个数」分类:单列索引、联合索引。
B+ tree
InnoDB中使用 B+ tree 来组织数据
存储方式
InnoDB 的数据是按「数据页」为单位来读写的,数据库IO最小的单位也是页,默认大小是 16KB
页的数据结构
- file header(内含页的双指针,pre,next
- page header(meta data of page
- 最小最大record(页内record的虚拟单链表的头和尾
- user record space,free space
- file tailer
数据页中的records按照「主键」顺序组成单向链表,头是inifimun,尾是supremun
(单向链表的特点就是插入、删除非常方便,但查询要遍历一遍,所以引入页目录
首先,对单链表分组,规则为:
- 第一个分组中的记录只能有 1 条记录;
- 最后一个分组中的记录条数范围只能在 1-8 条之间;
- 剩下的分组中记录条数范围只能在 4-8 条之间。
页目录就是由多个槽组成的,槽相当于分组记录的索引,指向的是这个组的主键最大的记录
(这样在一个页中根据「主键」查询一个record,可以先二分页目录找到分组,然后再遍历组内的record即可
B+ tree(page as node)
简单来说,是一个 自平衡的 多叉 搜索树,可以限制树的深度很小,保证高效的查询时间
规则
- 只有叶子节点才存放了数据,非叶子节点仅用来存放节点(页)地址作为索引。
- 非叶子节点分为不同层次,通过分层来降低每一层的搜索量;
- 每一层节点都按照索引键大小排序,构成一个双向链表,便于范围查询;
查询方式
下篇
聚簇索引和二级索引
下篇