单表访问方式

参考文章:《MySQL是怎样运行的:从根儿上理解MySQL》

我们本章只看单表的访问方式,整体上可以分为两大部分全表扫描和根据索引进行扫描,全表扫描就不说了,索引扫描又可以分为以下几种

  • 根据主键或者唯一二级索引的等值查询 const 非常快 
  • 普通二级索引等值查询 ref,  如果是联合索引的话,最左边的连续索引列是与常数进行等值比较就可能采用ref的访问方式 
  • ref or null ,我们不仅想要找出某个二级索引列的值等于某个常数的记录,我们还想把值为null的记录也找出来
  • 针对索引列的范围查询 range 
  • 直接扫描整个索引 index  ,无法使用ref,但是要查询的所有列都是索引中
     

再简单说说range的几种情况

  1. 所有所有条件都可以使用某个索引,如果用AND连接,取并集,如果用or连接,取交集。
  2. 有的搜索条件无法使用索引的情况,如果用AND连接,可以直接抹取,如果用OR连接,则是直接全表查询

二级索引 + 回表中需要注意的事情:一般(有特殊情况)只能用到单个二级索引进行查询

SELECT * FROM single_table WHERE key1 = 'abc' AND key2 > 1000;

两个字段都有索引,那么查找过程是:先用key1 索引查询,然后回表查到完整的结果,回表的完整结果对key2进行过滤。

索引合并

一:Intersection 合并 ,意思是说:某个查询可以使用多个二级索引,从多个二级索引查询的结果中取交集。 

SELECT * FROM single_table WHERE key1 = 'a' AND key3 = 'b';

具体步骤为:

  • 从 index_key1二级索引对应的B+树中取出key = 'a'的相关记录
  • 从index_key3二级索引对应的B+树中取出来key = 'b'的相关记录
  • 二级索引的记录都是由索引列 + 主键构成的,所以我们可以计算这个两个结果集中的id值的交集
  • 按照上一步生成的id值列表进行回表操作

为什么不用单个二级索引 + 回表的方式 + 筛选 的方式进行查询? 

那就需要分析两种方式的成本了。 

只读取一个二级索引的成本 由 按照某个搜索条件读取一个二级索引 + 根据二级索引得到的主键值进行回表操作 + 过滤其他搜索条件

读取多个二级索引之后取交集的成本 由 按照不同的搜索条件分别读取不同的二级索引 + 多个二级索引得到的主键进行交集 + 然后进行回表操作

虽然读取多个二级索引比读取一个二级索引消耗性能,但是读取二级索引的操作是顺序I/O,回表操作是随机I/O 。当对回表操作的性能节省大于一个二级索引查找性能的时候,就会用这种取交集的方式。 

Intersection索引合并适用的条件(必要但是不充分)

  • 二级索引是等值匹配 ,联合索引的话,必须每个列都等值匹配
  • 主键列可以是范围匹配

对于情况一,原因是,只有按照上述要求,根据二级索引查询出来的结果集是按照主键值进行排序的,如果是已经排过序的话,后面取交集的过程就会很方便。

对于情况二,我们使用二级索引进行查询,然后直接在二级索引查询的结果上直接使用主键筛选一下即可。

二:Union合并

三:Sort-Union合并

关于索引合并,我总结了一篇实战:

关于range访问方式,我总结了一篇实战博客:

你可能感兴趣的:(MySQL,数据库)