04 | 05 深入浅出索引
在 MySQL 中,索引是在存储引擎层实现的,所以并没有统一的索引标准,即不同存储引擎的索引的工作方式并不一样。而即使多个存储引擎支持同一种类型的索引,其底层的实现也可能不同。
索引常见模型
模型 | 特点 | 场景 | 使用 |
---|---|---|---|
哈希表 | 键值存储数据 | 等值查询 | Memcached 及其他一些 NoSQL 引擎 |
有序数组 | 有序数组存储数据 | 等值查询和范围查询 | |
B+树 | 适配磁盘的的访问模式,可以减少单词查询磁盘的访问次数 | 广泛应用在数据库引擎 | InnoDB |
跳表 | Redis | ||
LSM树 |
平衡二叉树、B树、B+树、B*树 : https://zhuanlan.zhihu.com/p/27700617
InnoDB 的索引模型
在 InnoDB 中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。InnoDB 使用了 B+ 树索引模型,所以数据都是存储在 B+ 树中的。
每一个索引在 InnoDB 里对应一颗 B+ 树。
索引类型又分为主键索引(聚簇索引)和非主键索引(二级索引)
- 主键索引:叶子节点存都是整行数据
- 非主键索引:叶子节点内容是主键的值。
基于主键索引和普通索引的查询的区别?
普通索引查询方式,需要先扫描普通索引的 B+ 树,找打对应的主键 ID, 再到 ID 索引树搜索一次,这个过程称为回表。
覆盖索引:索引拥有搜索需要的数据,无需回表。
最左前缀原则
B+ 树这种索引结构,可以利用索引的 "最左前缀",来定位记录。
在建立联合索引时,如何安排索引内字段顺序。
原则1:如果可以通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
原则2:空间。
索引下推
在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
例子:name like 'k%' and age >10, 存在联合索引 (name,age),
Mysql 5.6 之前,会对匹配的数据进行回表查询。
Mysql 5.6 之后,会先过滤掉 age < 10 的数据,再进行回表查询,减少回表率,提升检索速度。
索引维护
B+ 树为了维护索引的有序性,在插入新值和删除数据时需要做必要的维护。
页分裂:在新增数据时,如果相邻两个数据页已经满了,需要申请一个新的数据页,然后挪动部分数据过去。
页分裂会降低插入的性能和数据页的利用率。
页合并:当相邻的两个页由于删除了数据,利用率很低之后,会将数据也做合并。
自增主键与业务主键的区别:
-
性能
- 自增主键的插入,往往是追加操作,不需要挪动数据,不易造成页分裂问题。
- 业务主键无法保证有序插入,需要大量挪动数据,造成页分裂,写成本太高,影响性能,降低数据页利用率。
-
空间
- 主键长度越小,普通索引的叶子节点也就越小,占用空间越小。