mysql 索引基本概念

1. 什么是索引?mysql

索引是一种数据结构,能够帮助咱们快速的进行数据的查找.sql

2. 索引是个什么样的数据结构呢?数据结构

索引的数据结构和具体存储引擎的实现有关, 在MySQL中使用较多的索引有Hash索引,B+树索引等,而咱们常用的InnoDB存储引擎的默认索引实现为:B+树索引.函数

3. Hash索引和B+树全部有什么区别或者说优劣呢?性能

首先要知道Hash索引和B+树索引的底层实现原理:优化

hash索引底层就是hash表,进行查找时,调用一次hash函数就能够获取到相应的键值,以后进行回表查询得到实际数据.B+树底层实现是多路平衡查找树.对于每一次的查询都是从根节点出发,查找到叶子节点方能够得到所查键值,而后根据查询判断是否须要回表查询数据.code

那么能够看出他们有如下的不一样:排序

  • hash索引进行等值查询更快(通常状况下),可是却没法进行范围查询.

由于在hash索引中通过hash函数创建索引以后,索引的顺序与原顺序没法保持一致,不能支持范围查询.而B+树的的全部节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也相似),自然支持范围.索引

  • hash索引不支持使用索引进行排序,原理同上.字符串

  • hash索引不支持模糊查询以及多列索引的最左前缀匹配.原理也是由于hash函数的不可预测.AAAAAAAAB的索引没有相关性.

  • hash索引任什么时候候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候能够只经过索引完成查询.

  • hash索引虽然在等值查询上较快,可是不稳定.性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差.而B+树的查询效率比较稳定,对于全部的查询都是从根节点到叶子节点,且树的高度较低.

所以,在大多数状况下,直接选择B+树索引能够得到稳定且较好的查询速度.而不须要使用hash索引.

4. 上面提到了B+树在知足聚簇索引和覆盖索引的时候不须要回表查询数据,什么是聚簇索引?

在B+树的索引中,叶子节点可能存储了当前的key值,也可能存储了当前的key值以及整行的数据,这就是聚簇索引和非聚簇索引. 在InnoDB中,只有主键索引是聚簇索引,若是没有主键,则挑选一个惟一键创建聚簇索引.若是没有惟一键,则隐式的生成一个键来创建聚簇索引.

当查询使用聚簇索引时,在对应的叶子节点,能够获取到整行数据,所以不用再次进行回表查询.

5. 非聚簇索引必定会回表查询吗?

不必定,这涉及到查询语句所要求的字段是否所有命中了索引,若是所有命中了索引,那么就没必要再进行回表查询.

举个简单的例子,假设咱们在员工表的年龄上创建了索引,那么当进行select age from employee where age < 20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询.

6. 在创建索引的时候,都有哪些须要考虑的因素呢?

创建索引的时候通常要考虑到字段的使用频率,常常做为条件进行查询的字段比较适合.若是须要创建联合索引的话,还须要考虑联合索引中的顺序.此外也要考虑其余方面,好比防止过多的全部对表形成太大的压力.这些都和实际的表结构以及查询方式有关.

7. 联合索引是什么?为何须要注意联合索引中的顺序?

MySQL可使用多个字段同时创建一个索引,叫作联合索引.在联合索引中,若是想要命中索引,须要按照创建索引时的字段顺序挨个使用,不然没法命中索引.

具体缘由为:

MySQL使用索引时须要索引有序,假设如今创建了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,若是name相同,则按照age排序,若是age的值也相等,则按照school进行排序.

当进行查询时,此时索引仅仅按照name严格有序,所以必须首先使用name字段进行等值查询,以后对于匹配到的列而言,其按照age字段严格有序,此时可使用age字段用作索引查找,,,以此类推.所以在创建联合索引的时候应该注意索引列的顺序,通常状况下,将查询需求频繁或者字段选择性高的列放在前面.此外能够根据特例的查询或者表结构进行单独的调整.

8. 建立的索引有没有被使用到?或者说怎么才能够知道这条语句运行很慢的缘由?

MySQL提供了explain命令来查看语句的执行计划,MySQL在执行某个语句以前,会将该语句过一遍查询优化器,以后会拿到对语句的分析,也就是执行计划,其中包含了许多信息. 能够经过其中和索引有关的信息来分析是否命中了索引,例如possilbe_key,key,key_len等字段,分别说明了此语句可能会使用的索引,实际使用的索引以及使用的索引长度.

9. 那么在哪些状况下会发生针对该列建立了索引可是在查询的时候并无使用呢?

  • 使用不等于查询,
  • 列参与了数学运算或者函数
  • 在字符串like时左边是通配符.相似于'%aaa'.
  • 当mysql分析全表扫描比使用索引快的时候不使用索引.
  • 当使用联合索引,前面一个条件为范围查询,后面的即便符合最左前缀原则,也没法使用索引.
相关文章
相关标签/搜索