采访时有粉丝被问到,为什么SQL语句命中索引比不命中索引快?虽然我自己知道答案,但被问到的那一刻,我不知道如何组织单词。今天小编就来给大家深度解析一下。1、索引的作用想象一下,有一本字典,里面有几十万个词,厚几百页,里面的词是乱序排列的。如果不使用目录,我们如何从字典中找出需要的单词呢?毫无疑问,我们只能一页一页地翻着。显然,这是一部反人类的作品。我们必须想到的是先看目录,然后找到相关的词或部首,然后找到对应的页码再搜索我们要找的正文,这样效率会大大提高。其实目录就是一种索引,我们说的数据库索引的思想和目录的思想是一脉相承的。数据库索引的主要作用是帮助我们快速的检索到想要的数据,而不至于每次查询都要做全局扫描。假设在不使用任何算法的情况下,我们要查询这10万条记录中的一条,最坏情况下,我们需要遍历10万次。但是如果使用二分查找算法,只需要执行log220000次,也就是14.287712次。这意味着我们只需要对排序后的值进行14次搜索,然后我们就可以使用二分查找来找到想要的唯一值。常见的索引数据结构包括B-tree和B+-tree。下面以MySQL的InnoDB引擎为例,分析一下索引的工作原理。2.索引执行原理我们知道MySQL的InnoDB引擎采用的是B+树数据结构。当我们执行SELECT语句查询数据时,InnoDB需要从磁盘中读取数据,这个过程会涉及到磁盘和磁盘的随机性。IO,我们来看这样一个图:系统会将数据的逻辑地址传递给磁盘,磁盘控制电路根据寻址逻辑将逻辑地址翻译成物理地址。也就是确定要读取的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要把磁头放在这个扇区上。为了达到这样的一个点,磁盘将继续旋转。旋转磁头下方的目标扇区,使磁头找到相应的磁道。也会有寻道时间和旋转时间的损失。很明显,磁盘IO过程的性能开销是非常大的,尤其是查询的数据量比较大的时候。因此,在InnotDB中,只是简单地为存储在磁盘上的数据建立一个索引,然后将索引数据和索引列对应的磁盘地址以B+树的形式存储起来。我们看这样一张图:当我们需要查找目标数据时,我们只需要根据索引从B+树中找到目标数据即可。由于B+树中有很多子树,所以只需要很少的磁盘IO就可以找到目标数据。至于B+树的数据结构,这里就不分析了。以前的视频大家可以去我的个人主页看。3.索引的缺点虽然使用索引可以减少磁盘IO次数,提高查询效率,但是不能建立过多的索引。如果一个表中所有字段的索引都很大,也会造成性能下降。想象一下,如果一个索引和一个表一样长,检查起来又会是一种开销。这就好比字典的目录很详细,但是它的长度却和所有的单词一样长。这时候目录本身的效率就大大降低了。该指数有任何缺点吗?必须有,索引可以提高查询的读性能,反之则会降低写性能。当有索引时,如果你改变一条记录,或者在数据库中插入一条新记录,它会执行两次写操作(一次写入记录本身,另一次更新索引)。因此,在定义索引时,必须牢记以下几点:对表中的每个字段都建立索引会降低写入性能。建议对表中具有唯一值的字段进行索引。在关系数据库中充当外键的字段必须建立索引,因为它们有助于跨多个表进行复杂查询。索引也使用磁盘空间,所以在选择要索引的字段时要小心。
