1.索引优化的必要性

  索引优化是对查询性能优化的最有效的手段,能够轻松将查询性能提升几个数量级,创建一个真正的最优索引至关重要。且与查询密不可分。

2.索引基础

  (29条消息) 一文搞懂MySQL索引(清晰明了)_Free Joe的博客-CSDN博客_mysql索引

3. B-Tree索引

  其对如下类型查询有效:

    a.全值匹配:对索引中的所有列进行匹配

    b.最左前缀匹配:匹配索引的第一列

    c.匹配列前缀:匹配某一列值的开头部分

    d.匹配范围值

    e.精确匹配某一列并范围匹配另一列

    f.只访问索引的查询

  限制:

    a.如果不是最左列开始查找,则无法走索引

    b.不能跳过索引列,如果三个列作为索引,无法单独去匹配第一列和第三列

    c.范围查询无法走索引,末尾模糊匹配无法走索引

4.哈希索引

  仅有精确匹配索引才有效,Mysql引擎中,memory引擎支持哈希索引,不仅如此,其还支持非唯一哈希索引。哈希索引只包含哈希值和指针,所以仍然需要读取行。其为散列放置,无法进行排序。

5.索引的优点

  a.大大减少了服务器需要扫描的数据量

  b.帮助服务器避免排序和临时表

  c.将随机I/O变成顺序I/O。(随机I/O:假设我们所需要的数据是随机分散在磁盘的不同页的不同扇区中的,那么找到相应的数据需要等到磁臂(寻址作用)旋转到指定的页,然后盘片寻找到对应的扇区,才能找到我们所需要的一块数据,一次进行此过程直到找完所有数据,这个就是随机IO,读取数据速度较慢。顺序I/O:假设我们已经找到了第一块数据,并且其他所需的数据就在这一块数据后边,那么就不需要重新寻址,可以依次拿到我们所需的数据,这个就叫顺序IO。)

6.高性能索引策略

  a.独立的列:索引不应该是表达式的一部分,也不应该是函数的参数

  b.前缀索引和索引选择性:对于BLOB/TEXT等类型,必须采用前缀索引,因为Mysql并不支持索引这些列的完整长度。适当选择前缀的长度,当前缀的出现次数和实际列值的出现次数相仿时,证明前缀选取比较合适。

  c.多列索引:不应该为每个where条件单独加上索引,而应该按照合适的顺序创建多列索引。对于or条件,单列索引会走全表扫描,但若使用联合union关键字,会让查询同时走两个索引。但是实际上,采用多单列索引,会导致大量资源消耗。

  d.选择合适的索引列排序:当不要考虑排序和分组时,将选择性高的列放在索引的最前列通常比较优秀。然后并不能只考虑索引列的选择性,也和查询的具体值、值的分布有关。

  e.聚簇索引:实际上聚簇索引并不是一种单独的数据类型而是一种数据存储方式。表有聚簇索引时,它的数据实际上存放在索引的叶子页中。通常来说,数据行和相邻的键紧挨着。

7.对于聚簇索引

  InnoDB通过主键来聚集数据,也就是说聚簇索引的B+Tree上的叶子结点所存储的key总是主键,如果没有定义主键,InnoDB会选择一个唯一的非空索引代替,如果没有这样的索引,InnoDB会隐式地定义一个主键来聚集(存储)数据,这个隐式的主键被称为rowID。这样做的目的是为了避免随机聚簇索引,保证顺序写入。对于非聚簇索引,InnoDB通常在叶子节点上存储的是数据行的主键值,命中非聚簇索引时,InnoDB会拿到此主键值再去聚簇索引中查询所需要的记录,这个过程称为回表。正是由于如此,所以通常来说聚簇索引的查询效率要比非聚簇索引高。在InnoDB中,聚簇索引就是整个表。并且,尽量按照主键的顺序插入数据,尽可能采用单调增加的聚簇键的值来插入新行。

  什么时候顺序主键会造成坏的结果?当并发插入时,可能导致间隙锁的竞争,降低性能。

8.覆盖索引