由于本篇文章侧重于 MySQL 索引的应用,所以并没有完全详细的介绍 B+ 树索引,但 B+ 树索引又是 MySQL 中默认使用的索引,所以关于 B+ 树索引细节介绍可见 B+ 树索引
索引是一种用于快速查询和检索数据的数据结构,其本质可以看作是一种排好序的数据结构
索引类似于书的目录,如果一本书没有目录,那么对于读者来说就是一场噩梦,目录可以加快我们查找的速度和效率,索引的作用也一样
索引底层数据结构有很多种类型,常见的索引结构:B 树、B+ 树、Hash 表、红黑树。在 MySQL 中,无论是 InnoDB 存储引擎,还是 MyISAM 存储引擎,使用的都是 B+ 树索引
优点:
加快查询检索数据的速度
可以通过创建唯一索引保证数据的唯一性
缺点:
空间成本:MySQL 中每一个索引都对应一个 B+ 树,需要一定的页来存储索引
时间成本:在执行增删改操作时,需要维护索引的正确性,会消耗一定时间
注意:有时候「二级索引 + 回表」的速度并不一定比「全表扫描」快,因为可能回表次数过多,而且页在物理存储上较为分散,需要进行多次磁盘 IO 将对应页加载到内存中,耗时大
将索引列映射到哈希表中,即:key = 索引列的值,value = 记录的位置,通过 key 可以快速获取记录的位置,在没有哈希冲突的情况下时间复杂度 O(1),可以用链地址法或开放定址法解决哈希冲突
MySQL 之所以没有使用 Hash 表作为索引的底层实现,是因为 Hash 表不支持顺序查询和范围查询,只支持每次查询一个
B 树也称 B- 树,全程为多路平衡查找树,B+ 树是 B 树的一个变体。B 树和 B+ 树中的 B 是Balanced
的意思。目前大部分数据库系统及文件系统都采用 B- 树或其变体 B+ 树作为索引底层实现
B 树和 B+ 树的区别:
B 树的所有节点既存放键 (key),也存放数据 (data);而 B+ 树只有叶子节点存放 key 和 data,其它非叶子节点只存放 key
B 树的叶子节点都是独立的;B+ 树的叶子节点间通过双向链表连接
B 树的检索过程相当于对范围内的每个节点的关键字做二分查找,可能还没到叶子节点就结束了;而 B+ 树的检索过程很稳定,任何查找都是从根节点到叶子节点
从数据结构维度划分:
B+ 树索引:MySQL 中默认的索引结构,同层节点间双向链表连接,节点内单向链表连接
Hash 索引:通过键值对的形式,一次即可定位
从底层存储方式划分:
聚簇索引:InnoDB 中的主键索引就属于聚簇索引,叶子节点存放完成用户记录,非叶子节点存放目录项纪录。数据和索引在一起,索引即数据,数据即索引
从应用维度划分:
主键索引:InnoDB 中的主键索引就属于聚簇索引,表中只会有一个主键索引,主键具有的特性该主键索引都具有,如:值唯一,且不为 NULL
普通索引:InnoDB 中的普通索引就属于 二级索引
唯一索引:值唯一,可以有 NULL
覆盖索引:索引列包含查询列表
联合索引:索引包含多个列
前缀索引:为了降低索引占用的空间,可以只将一个字段的前缀作为索引
全文索引:对文本的内容进行分词,然后搜索
选择合适的字段建立索引:频繁根据该字段查询
频繁更新的字段慎重建立索引:维护成本大
限制每张表索引数量 (5 个):索引会占用一定空间,虽然可以加快查询,但会减慢更新插入
尽可能建立联合索引而非单列索引:索引需要占用空间,联合索引可以减少空间的使用
注意避免冗余索引:比如建立了联合索引 (a, b),又建立了 单列索引 (a),就会出现冗余
字符串类型字段尽量使用前缀索引:可以减少空间的使用
避免索引失效:虽然建立了索引,但是没有使用使用,可以通过explain
查看执行计划
删除长期未使用的索引