MYSQL之SQL优化一

背景

创建字段和索引都是一样的test1和test2表。
id主键、age普通索引、id_card唯一索引、name无索引。
在这里插入图片描述

执行计划

通过explain可以查看sql的索引命中情况。

因为即使where条件包含了索引,也不一定会命中索引。因此我们假设where条件总是能命中索引。

type

type有以下几个值,性能而言,可以认为system>const>eq_ref>ref>range>index>ALL。

System:指系统表的查询,仅有一行的记录。,一般用不到。
Const:通过索引一次找到,比如where t.id = ‘1’。
eq_ref:唯一索引扫描,表中间只有一条记录对应,比如t.id = q.id。
Ref:非唯一索引扫描,返回匹配某个指的所有行,比如 country = ‘china’。
Range:只查询范围内的索引列,常常配合between、in、< >使用,因为只需要在树中查询范围数据,不需要查询整棵树,所以比index快。
Index:只查询索引列,但是需要获取所有。因为仅仅需要获取树中的全部数据,而不需要回归表,所以比all快。
All:全表查询。

Const

在这里插入图片描述

eq_ref

使用ID做关联查询时,关联条件左边的表会使用到这个索引,右边的表只是命中了普通索引index。
在这里插入图片描述

ref

使用id做关联条件查询可以命中eq_ref,如果使用其他唯一索引确无法命中。比如使用id_card唯一索引字段,关联条件左边的表只是命中了ref,右边的表还是命中index索引。
在这里插入图片描述
不建议使用select * 的原因是会使得索引失效,导致全表扫描,除非覆盖索引
在这里插入图片描述

在这里插入图片描述

Range

范围查询,查询条件应该也包含在where中,才会命中索引
在这里插入图片描述
虽然age也是索引,但还是全表扫描了,并没有命中range,因为select 的列不包含在where中
在这里插入图片描述
查询条件为ID主键,select 字段即使不是索引列,也会命中range,因为ID索引包含了全量数据
在这里插入图片描述

index

满足以下任一条件,至少能命中index:

  1. select条件包含索引,没有where过滤条件
  2. select条件包含索引列,且都在where条件中
    在这里插入图片描述
    如果select条件有多个,且不是组合索引的时候,无法使用索引
    在这里插入图片描述

null也可以命中索引

select的字段能够命中索引,这条sql就可以命中索引,而以字段是否可以为null无关
在这里插入图片描述
在这里插入图片描述


版权声明:本文为qq_36180997原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。