浅谈mysql索引(上)

Posted 生信与计算机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈mysql索引(上)相关的知识,希望对你有一定的参考价值。

       索引这个词在我们日常生活的各个地方都能看见。比如你在图书馆可能就会看见“图书馆楼层索引”或“该楼层图书索引”的字样。索引的作用也很容易理解,那就是为了方便数据的检索。但是很显然,图书馆中的图书不仅仅只出现检索的需求,而且也有可能有同学要借书,有可能到了一批新书需要加入。当出现借书和添加新书的时候,图书馆的索引又应该怎么维护呢?

       与上面的例子相似,在mysql这种能存储海量数据的数据库中,必须也要有索引才行。mysql的整个系统结构如下:

       mysql中的索引是在存储引擎层上实现。我们知道mysql有多个不同的存储引擎,比如InnoDB,MyISAM等等。像我们一般常用的mysql5.7及以上的版本,默认的存储引擎都是innodb。从mysql使用者的角度来看,数据库中的所有数据都是以表的形式存储的。而在innodb内部实现中,一张表是由多个B+树共同组成。用B+树来实现一张表有很多优点,我们先来看一下什么是B+树。

       B+树是数据结构中的概念,下图是一颗B+树。它具有的主要特征如下:1. 含有n个关键字的非叶子节点会有n颗子树。非叶子节点不会保留关键字对应的记录,它只会保存这个关键字索引,记录都存储在叶子结点中。2. 所有叶子结点包含了全部的关键字和关键字对应的记录,这些叶子结点不仅结点内部关键字有序,而且结点与结点之间的关键字也按照从小到大(从大到小)的顺序链接起来。所有的叶子结点都在同一层。3. 一个关键字可能会在不同结点中重复出现,即孩子结点会包含父结点中的关键字,因此叶子结点中包含所有的关键字。


      B+树在mysql数据库上表现性能优良的原因在于,mysql数据库中表是需要存储到磁盘中的,也就是要进行磁盘I/O操作。如果磁盘I/O次数太多,一定会成为整个系统的瓶颈。磁盘一次寻道时间大概是10ms,1s只能寻道100次。1s一般可以读个50MB的数据就已经很不错了,而内存1甚至可以读4GB的数据。在mysql中一个innodb页的大小一般是16KB,每读一个数据页就需要访盘一次,一般情况下,mysql B+树的高度都不会超过3,也就是说,想到得到一行数据,大约需要访盘3次即可。将数据页放入内存之后,通过二分查找的查找方式,即可很快找到需要查询的数据。

       在Innodb中,表都是根据主键顺序以索引的形式存放的。这种存放方式称为索引组织表。当我们创建一张mysql表时,一般会指定一个主键,即使没有指定主键,mysql也会默认生成row ID来作为表的主键。主键索引,也称为聚簇索引,它采用的就是上述的B+树结构来组织的。主键索引的特点在于,它的叶子结点中关键字对应的值,就是表中行。非主键索引,也称为二级索引,同样是一颗B+树的结构,它和主键索引的区别在于,非主键索引对应的B+树叶子结点中关键字对应的值,是主键。也就是说如果在mysql表中进行查询时,如果采用的是非主键索引进行查询,那么在找到指定的关键字之后,还需要根据关键字对应的主键,去主键索引中找到这一整条数据(行),这个操作也称为回表。简单来说,主键索引:key是主键的值,value是整行数据。普通列索引:key是索引列的值,value是主键的值。

        通过以上分析,实际上就已经知道了在表中添加一行数据时,实际上需要在B+树中添加一个关键字。这里就需要考虑B+树的分裂与合并。假如在添加一个关键字的时候,对应的数据页已经满了,那么此时为了维护B+树的特性,需要使用一个新的页来进行关键字的迁移。很明显,这种操作肯定会降低性能。除了性能外,页分裂操作还影响数据页的利用率。原本放在一个页的数据,现在分到两个页中,整体空间利用率降低大约 50%。实际上这里就可以理解为什么通常情况下,需要使用自增主键了。自增主键,也就是主键的值会逐渐增大,对应于B+树中,每次新增的关键字都是最大,所以直接添加到链表最后一个结点的末尾即可,不会产生页分裂的情况,减少磁盘I/O,在有大量写操作的场景下,这也就大大提高了数据库的性能。但是使用自增主键,而不使用业务主键,需要考虑的另一个方面是:当使用自增主键时,再给其他列进行索引之后,需要进行回表操作,相当于要多几次访盘操作。当采用业务字段作为主键时,需要综合考虑数据库的性能和存储空间。

以上是关于浅谈mysql索引(上)的主要内容,如果未能解决你的问题,请参考以下文章

浅谈mysql性能优化

浅谈 MySQL 索引优化分析

浅谈MySQL--Sorted Index Builds

浅谈MySQL中优化sql语句查询常用的30种方法

浅谈MySQL中优化sql语句查询常用的30种方法

浅谈MySQL中优化sql语句查询常用的30种方法