MySQL(InnoDB)是如何利用索引加快查询速度的

1,543 阅读3分钟

你的数据库的表中可能存储了大量数据,想从海量数据中更快速查找到想要的数据是一件有意思的事情,于是聪明的前辈设计了索引这种东西,帮助缩短查找时间。

不使用索引

无索引时的查找就像在图书馆的书架上,一本一本的查看这本是否是自己想要的那本;又像是一个简单的数组,你需要从前往后或者从后往前遍历,最终找到自己想要的数据,时间复杂度 O(n).

随着数据量增加,查找速度也会随之变慢,最终慢到怀疑人生。

使用索引

1.我想象中的索引

如果你写过一些 JavaScript,可能会把 object 通过 key 查找到 value 的过程理解为索引。没错,我就是这样理解的。在学习 mysql 的过程中,下意识的把 mysql 索引错误的理解成了对 Table 中某个 cell 的索引,再接下来就是一头雾水,无法理解数据库是如何通过“这种”索引形式提升查找效率的。

2.现实中的索引

实际上,InnoDB 使用 B+ Tree 索引模型,数据都保存的 B+树中。创建索引的操作实际上是对特定的列(字段)建立索引。

假设我们有这样一张表,包含字段(id, time,name),其中 id 是主键(Primary Key),对 time 字段(时间戳)建立索引,再次强调一下,是对列建立索引。

建立索引后,就形成了一颗描述 time 字段的B+树。了解过二叉树的同学应该知道,数据量很大时,树形结构的查找比简单粗暴的遍历查找效率要高出很多。时间复杂度 O(log N),换句话说查找次数和树的高度相关。因此每次查找,你可以很明确的被引导至下一个节点,同时过滤掉大量不符合条件的数据。

为了简化,这里做一些简写,树(time)表示基于 time 字段建立的索引结构。其他字段类似。

回到 InnoDB 的索引,通过查找树(time),我们找到一个叶子节点,节点内的值是主键 id 字段存储的值。拿到主键 id 的值以后,再去树(id)中,通过刚才的 id 做树查找,最终在树(id)中找到一个叶子结点(树(id)的叶子),这个节点中存储的,就是 Table 里 N 行数据中的一行,也就是我们想要获得那一行。通过非主键索引执行查询操作,实际上查询了两棵树。

小结

文章看到一半的同学可能应该就已经领悟索引的原理了,通过创建合适的数据结构能够起到事半功倍的作用。对于实际业务中经常要查询的字段,建立索引或许是个不错的选择。

Tips

如果阅读文章的同学对树、复杂度这些概念比较生疏,可以查阅一些数据结构算法方面的资料帮助理解。

以上