本文的重点在于如何构建一个高性能的MySQL索引,从中你能够学到如何分析一个索引是否是好索引,以及如何构建一个好的索引。sql
一个索引的常见误区是为每一列建立一个索引,以下面建立的索引:架构
t表里有三列,而且为每列建立了一个索引。建立索引的人为了可以快速访问表中的任何一列,所以为每一列添加了一个单独的索引。在多个列上建立索引一般并不能很好的提升MySQL查询性能,虽说MySQL 5.0以后引入了索引合并策略,能够将多个单列索引合并成一个索引,但这并不老是有效的。同时建立多个索引的时候还会增长数据插入的成本,在插入数据的时候须要同时维护多个索引的写入操做。函数
看下面这条sql语句:性能
1.select name from student where id + 1 = 5学习
即便咱们在student表的id列上创建索引,上面的这条SQL语句也没法使用索引。SQL语句中索引字段不能是表达式的一部分,也不能是函数的参数。优化
尽可能不要在一个很长的列上使用索引,不然会致使索引占用的空间很大,同时在进行数据的插入和更新的时候意味着更慢的速度。所以使用uuid列做为索引并非一个好的选择。从上一篇文章中咱们能够知道,为了加快数据的访问索引是须要常驻内存的,假如说咱们把64位uuid做为索引,那么随着表中数据量的增长索引的大小也在急剧增长。同时由于uuid并无顺序性,所以在数据插入的时候都须要从根节点找到当前索引的插入位置,若是同一个节点中的索引大小达到上限,还会致使节点分裂,更加下降了插入速度。ui
建立索引另一个须要考虑的是索引的选择性,一般状况下咱们会使用选择性高的列做为索引,可是也不必定一直是这样,下一节会介绍如何权衡索引的选择性。spa
在选择索引的顺序的时候有一个原则:将索引选择性最高的列放在左侧,同时索引的顺序要与查询索引的顺序一致,而且要兼顾考虑排序和分组的须要。在一个多列B树多列中索引的顺序意味着索引首先按照最左侧的列进行排序,其次是第二列。因此不管是where语句仍是order by语句都须要尽可能知足这个顺序,这样才能更好的使用索引。指针
列的选择性高的含义是经过这一列可以更多的过滤掉无用的数据,举个极端的例子,若是把自增id建成索引那么它的选择性是最高的,由于会把无用的数据都过滤掉,只会剩下一条有效数据。咱们能够经过下面的方式来简单衡量某一个列的选择性:视频
1 select count(distinct columnA)/count(*) as selectivity from table
当上面的数据越大的时候意味着columnA的选择性越高。这种方式提供了一个衡量平均选择性的办法,可是也不必定是有效的,须要具体状况具体分析。
当遇到特别长的列,但又必需要创建索引的时候能够考虑创建前缀索引。前缀索引的含义是把某一列的前N个字符做为索引,建立前缀索引的方式以下:
alter table test add key(columnA(5));
上面这个语句就是把columnA的前5个字符建立为前缀索引。前缀索引是一种使索引更小、更快的有效办法。可是前缀全部有一个缺点:MySQL没法使用前缀索引来作order by和group by,也没法使用前缀索引作覆盖扫描。
聚簇索引表明一种数据的存储方式,表示同一个结构中保存了B-Tree索引和数据行。也就是说当创建聚簇索引的时候实际的数据行存放在索引的叶子节点上。这也决定了每一个表只能有一个聚簇索引。
聚簇索引组织数据的方式以下图所示:
从图中能够看到索引的叶子节点和数据行是存放在一块儿的,这样的好处是能够直接读取到数据行。在建立表的时候若是咱们不显式指定聚簇索引,那么MySQL将会按照下面的逻辑来选择聚簇索引:首先会经过主键列来汇集数据,若是没有主键列那么会选择惟一的非空索引来替代。若是尚未这样的索引那么会隐式的建立一个主键列来做为聚簇索引。
聚簇索引优势:
一、相关数据存放在一块儿,检索的时候下降IO的次数
二、数据访问更快
三、使用覆盖索引扫描的查询能够直接使用节点中的主键值
在使用上面的优势的时候聚簇索引也有必定的缺点:
一、聚簇索引将数据汇集在一块儿限制了插入速度,插入速度比较依赖于主键的顺序
二、更新索引的时候代价会变高
三、二级索引的访问的时候须要查找两次
非聚簇索引一般被称为二级索引,与聚簇索引的不一样在于,非聚簇索引的叶子节点存放的是数据的行指针或者是一个主键值。这样在查找数据的时候首先定位到叶子节点上的主键值(或者行指针),而后经过主键值再到聚簇索引中查找到对应的数据。从中咱们能够看到对于非聚簇索引的查询须要走两次索引。下图是一个非聚簇索引:
这个索引是InnoDB中的耳机索引,叶子节点中存储的是索引和主键。对于MyISAM叶子节点存储的是索引和行指针。
若是一个索引包含或者说覆盖全部须要查询的字段的值,那么就称为覆盖索引。覆盖索引能够极大的提升查询的效率,若是咱们的查询中只查询索引,而不用去回表那应该最好不过了。
一般咱们使用explain关键字来查看一个查询语句的执行计划,经过执行计划咱们能够了解到查询的细节。若是是覆盖索引,咱们会看到执行计划的Extra列里有”Using Index”的信息。在查询语句中通常咱们但愿是where条件中的语句尽可能能被覆盖,而且顺序要跟索引的保持一致。还有一个须要注意的点是MySQL不能在索引中使用like操做,这样会致使后面的索引失效。
本文主要讲了几种索引的原理以及如何构建一个高性能的索引。索引的优先是一个渐进的过程,随着数据量和查询语句的不一样而发生变化,重要的是了解索引的原理,这样作出正确的优化。下一篇文章中将会介绍explain关键字,教你如何来看执行计划,以及如何判断一个查询语句是否须要优化的。
那如何学习才能快速入门并精通呢?
当真正开始学习的时候不免不知道从哪入手,致使效率低下影响继续学习的信心。
加架构QQ群:681065582,免费领取以上学习资料
但最重要的是不知道哪些技术须要重点掌握,学习时频繁踩坑,最终浪费大量时间,因此有一套实用的视频课程用来跟着学习是很是有必要的。