MySQL数据库索引

青年:为什么需要索引?

大师:这是为了加速数据查找.

青年:嗯。。

大师:没懂?打个比方,你查字典是怎么查的?你会从头到尾一页一页翻吗?不,你会按拼音,偏旁,或者笔画,找到字所对应的页码,然后再直接翻到对应的页码上.

青年:有点懂了

大师:你经常用MySQL,你知道MySQL使用什么数据结构吗?

青年:好像是叫B+树,但为啥叫B+树啊?

大师:B+树是一种改进的B树。B树的B是Balanced的缩写意思,Balanced Tree,就是平衡树。平衡意思是它会保持树的左右两边节点数量差距尽量小。

青年:B+树相对B树改进在哪里呢?

大师:问得好。
一是在于所有叶子节点位于同一层,并且并且通过指针连接成一个有序链表
二是非叶子节点不存储数据,只存储索引信息。
三是B+树每个节点可以存储多个关键字,这些关键字按生序排列

青年:为什么要做这些改进,有啥作用?

大师:是这样的。
第一,叶子结点连成链表,是为了让范围查询更高效。
第二,非叶子结点不存数据,这样索引就更适合放到内存里,
第三,节点可以存储多个关键字,那么树的高度就会相对低一点,查询的耗时跟树的高度是相关的,树的高度越低,查询性能就越好

青年:原来如此。但是我知道这些有什么用呢?

大师:别急呀。作为程序员你经常需要优化SQL的性能。要优化性能,理解B+树的特点是关键所在。
你听我慢慢道来。MySQL数据表是一颗使用主键搭建起来的B+树。叶子结点上存放着表的所有行。
其他索引也是B+树,只不过叶子结点上存放的是主键。

大师:当一个query使用了索引时,往往先是从索引找到主键,再根据主键去主表查具体数据行
根据主键去主表查具体数据行的这个操作叫做回表,它往往很慢,因为主表上的具体数据行存储再磁盘上而不是内存里。
磁盘的一次随机寻址大约1千万纳秒,而一次内存寻址只需要100纳秒,相差十万倍。
所以回表是要尽量避免的。如何避免呢,当query所需要查的列就在索引中时,就不需要回表了。这样的请求就会很高效

所以SQL优化的关键点就是

  1. SQL只查所需要的列
  2. 针对对高频的查询,设计索引,使得所需要的列全部都在索引中

青年:现在我明白了,为啥经常说禁止使用select *。原来是为了方便发现高频请求,以便设计索引。