Innodb查询优化器

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 查询优化器如何找到最优执行计划 优化器的主要作用就是为待执行的sql语句找到最优的执行计划,其基本优化方式如下: 等价变化规则 例如: 5=5 and a>5 改写成 a>5 a5 and a=5 基于联合索引,调整条件位置等 例如联合索引(name,age),当查询age=5 and name='zhangsan'会自动优化成name='zhangsan' and age=5来使用联合索引。

查询优化器如何找到最优执行计划

优化器的主要作用就是为待执行的sql语句找到最优的执行计划,其基本优化方式如下:

等价变化规则

例如:

5=5 and a>5 改写成 a>5
a<b and a=5 改写成 b>5 and a=5

基于联合索引,调整条件位置等

例如联合索引(name,age),当查询age=5 and name='zhangsan'会自动优化成name='zhangsan' and age=5来使用联合索引。

优化count 、min、max等函数

min函数只需找索引最左边,B+树最左边的子节点;

max函数只需找索引最右边,B+树最右边的子节点;

将可转换的外连接查询转换为内连接查询

覆盖索引扫描

例如如果对于name列做了索引,那么:

select id,name from user

也会使用覆盖索引,因为name在索引上,而id(主键)在其索引树的子节点上保存。优化器在选择要使用的索引时,也会考虑到是否会覆盖到覆盖索引。

子查询优化

select * from (select * from user where id=1)

这时候执行计划只会列出一个索引计划情况,而不是两个。因为语句被优化为了select * from user where id=1

外连接转换为内连接

并不是所有的外连接查询都必须以外连接查询进行。很多情况会让一个外连接等价一个内连接,MySQL在静态优化的部分进将SQL语句进行重写。转换成一个内连接。

提前终止查询

用了limit关键字或者使用不存在的条件,例如当id为非负时,select * from user where id=-1则会提前终止

IN的优化

先说一下or的逻辑,or会导致全表扫描,例如id列有1,2,3,4,5,6,7,8,9。如果有where id=1 or 2 or 3 ,那么会将全表的记录取出来依次和or条件比对,例如取出id=1,第一个条件匹配,放入结果集;id=2,第一个条件不匹配,继续匹配之后的条件,直至相符或全部不相符,然后再去比对下一条记录。

一般情况下in的逻辑和or的逻辑是相同的。

但是mysql对in进行了优化,例如id in(6,5,3,9,1),mysql会先进行排序,变成in (1,3,5,6,9),再采用二分查找的方式,先和二叉树顶点5比较,然后再进行左树或右树的比较。这样,in的效率就比or的效率高出很多。

Mysql的查询优化器是基于成本计算的原则。他会尝试各种执行计划,选择出最终方案。

执行计划

一条SQL只能使用一个索引

并不是一条整个SQL只能使用一个索引。

一个简单的表查询SQL语句一般情况下只会使用一个索引,但是存在有index_merge的情况,例如使用or 条件的时候,可能出现一个SQL出现多个索引。

如果是子查询,或者联合查询就一般看嵌套的层级,每一层都能使用到一个索引。

查看执行计划

使用explain或desc关键字。

_

id

id列表示select查询的序列号,标识执行的顺序

1、id相同,执行顺序由上至下

2、id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

3、id相同又不同即两种情况同时存在,id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行。上图示例中执行顺序为3->1->2。

select_type

select_type表示查询的类型,主要是用于区分普通查询、联合查询、子查询等。

SIMPLE:简单的select查询,查询中不包含子查询或者union

PRIMARY:说明查询中包含子部分,其最外层查询则被标记为primary

SUBQUERY/MATERIALIZED:SUBQUERY表示在select或where列表中包含了子查询,MATERIALIZED表示where 后面in条件的子查询

UNION:若第二个select出现在union之后,则被标记为union;

UNION RESULT:从union表获取结果的的select

table

table表示查询涉及到的表,直接显示表名或者表的别名,如果不是直接显示表名,如下:

<unionM,N> 由ID为M,N 查询union产生的结果
<subqueryN> 由ID为N查询生产的结果

type

type表示访问类型,sql查询优化中一个很重要的指标,结果值从好到坏依次是:

system > const > eq_ref > ref > range > index > ALL
system:表只有一行记录(等于系统表),const类型的特例,基本不会出现,可以忽略;

const:表示通过索引一次就找到了,const用于primary key或者unique索引,
       一般只有主键索引才会const,因为其他索引都要进行二次回表;

eq_ref:唯一索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描,
        一般为唯一索引,因为要进行回表,所以达不到const级别;

ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质是也是一种索引访问;

range:只检索给定范围的行,使用一个索引来选择行,例如where time>? and time<?;

index:Full Index Scan,全索引扫描,数据的搜索是通过索引的结构进行的,不代表覆盖索引全扫描,在extra中 using index 的额外信息才表示覆盖索引。

ALL:Full Table Scan,全表扫描,innodb中全表扫描就是扫描聚集索引的所有子节点

使用了索引进行搜索的级别是const、eq_ref、ref、range。index和all不是用索引进行了的搜索,而是对索引进行了遍历,全扫描。

一般情况下,项目中的sql语句至少要达到range级别。

possible_keys

查询过程中有可能用到的索引

key

实际使用的索引,如果为NULL,则没有使用索引

rows

根据表统计信息或者索引选用情况,大致估算出找到所需的记录所需要读取的行数

filtered

它指返回结果的行占需要读到的行(rows列的值)的百分比表示返回结果的行数占需读取行数的百分比,filtered的值越大越好

Extra

Extra是十分重要的额外信息

Using filesort:mysql对数据使用一个外部的文件内容进行了排序,而不是按照表内的索引进行排序读取,
      例如使用没有索引的字段排序:
        select * from user order by last_update_time
      文件排序和使用临时表排序都是比较耗费性能的。

Using temporary:使用临时表保存中间结果,也就是说mysql在对查询结果排序时使用了临时表,常见于order by 或 group by,例如:
        select max(last_update_time) from user group by last_update_time;
      临时表的引擎一般为memory或myisam,优先使用memory,因为memory数据存在内存中,IO效率要高很多,但memory默认16mb(可配置),超出后则使用myisam。

Using index:表示相应的select操作中使用了覆盖索引(Covering Index),避免了回表访问,效率高

Using where:使用了where过滤条件

select tables optimized away:基于索引优化MIN/MAX操作或者MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段在进行计算,
      查询执行计划生成的阶段即可完成。例如前面举的max的例子
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
存储 关系型数据库 MySQL
InnoDB中的索引方案
InnoDB中的索引方案
56 0
|
6月前
|
存储 SQL 关系型数据库
mysql 回表的代价(InnoDB)
mysql 回表的代价(InnoDB)
|
存储 SQL 缓存
MyISAM索引和InnoDB索引
MyISAM索引和InnoDB索引
|
存储 SQL 自然语言处理
MySQL索引简介 - InnoDB和MyISAM索引模型
MySQL索引简介 - InnoDB和MyISAM索引模型
99 0
|
存储 缓存 关系型数据库
Innodb存储引擎的索引组成
Innodb存储引擎的索引组成
|
存储 安全 关系型数据库
【Innodb 和mylsam存储引擎】
【Innodb 和mylsam存储引擎】
110 0
|
存储 关系型数据库 MySQL
|
存储 关系型数据库 索引
InnoDB 和 MyISAM 存储引擎的区别
InnoDB 和 MyISAM 存储引擎的区别
161 0
InnoDB 和 MyISAM 存储引擎的区别
|
存储 安全 关系型数据库
数据库引擎InnoDB与MyISAM区别
数据库引擎InnoDB与MyISAM区别
数据库引擎InnoDB与MyISAM区别
|
存储 关系型数据库 MySQL
InnoDB存储引擎中
InnoDB存储引擎中
113 0