Mysql 学习(十 二)查询优化 Explain

这篇具有很好参考价值的文章主要介绍了Mysql 学习(十 二)查询优化 Explain。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是Explain?

  • 一条查询语句经过Mysql查询优化器的各种基于成本和规则的优化后生成一个所谓的执行计划,而Explain 语句可以让我们知道执行计划的语法,从而我们有针对性的提升性能
  • 举例子:EXPLAIN SELECT 1
    Mysql 学习(十 二)查询优化 Explain
  • 由此我们得到了一些参数,而这些参数我们可以知道我们这个执行计划做了那些优化,由此我们也可以依据这个去优化我们的sql
  • 对应参数如下:
    • table:
    • id:
    • select_type:
    • partitions:
    • type:
    • possible_keys:
    • key:
    • key_len:
    • ref:
    • rows:
    • filtered:
    • Extra:
  • 接下来我们就来讲解对应参数的含义

table

  • 由前几节我们知道,无论查询怎么复杂,我们查询实际上算是对每个表进行单表查询,所以在执行explain 语法,table列上会存放这次查询的表名
  • 举个例子:EXPLAIN SELECT * FROM city
    Mysql 学习(十 二)查询优化 Explain
  • 上面是单表查询的,如果是连接查询,会怎么展示呢?
  • 举个例子:EXPLAIN SELECT * FROM city LEFT JOIN country on city.country_id = country.id
    Mysql 学习(十 二)查询优化 Explain
  • 从这里可以看到有两条记录,分别对应city表和country表,通过其他参数我们可以知道,我们访问这两个表分别使用了什么查询方式

id

  • 任何查询都会有select ,普通的查询里面可能只有一个select,但是又子查询这种复杂查询就可能会有多个select,但我们知道本质上我们还是把一个拥有多个select语句拆分成多个select语句,所以我们进行优化的时候,需要给每个select定义一个id,这样才好分析
  • 情况一:只有一个select ,举个例子:EXPLAIN SELECT * FROM city LEFT JOIN country on city.country_id = country.id
    Mysql 学习(十 二)查询优化 Explain
  • 情况二:有多个select,举个例子:EXPLAIN SELECT * FROM city WHERE country_id = (SELECT id FROM country where country = 'Austria')
    Mysql 学习(十 二)查询优化 Explain
  • 情况三:查询优化器可能对涉及子查询的查询语句进行重写,从而转换为连接查询。所以如果我们想知道查询优化器对某个包含子查询的语句是否进行了重写,直接查看执行计划就好了,比如:EXPLAIN SELECT * FROM city WHERE country_id in (SELECT id FROM country )
    Mysql 学习(十 二)查询优化 Explain
  • 情况四:union 子句,它会将多个查询的结果集合并起来并对结果集中的记录进行去重,会创建一个临时表,所以会产生一个id为null的记录,举个例子:EXPLAIN SELECT * FROM city UNION SELECT * FROM city
    Mysql 学习(十 二)查询优化 Explain

select_type

  • 每个select的查询都会有不同的属性,我们之前之所以定义id 主要是为了更好的优化select语句,让我们知道每个select执行了那些操作,而select_type属性就是为了更好研究
  • select_type 取值:
    • SIMPLE:查询中不包含UNION或者子查询的查询方案

    • PRIMARY:查询中包含UNION,UNION ALL或者子查询的大查询中,由几个小查询组成,其中最左边的查询就是PRIMARY

      • 举个例子:EXPLAIN SELECT * FROM city UNION SELECT * FROM city
        Mysql 学习(十 二)查询优化 Explain
    • UNION:对于包含UNION或者UNION ALL的大查询来说,它是由几个小查询组成的,其中除了最左边的那个小查询以外,其余的小查询的select_type值就是UNION

      • 举个例子:EXPLAIN SELECT * FROM city UNION SELECT * FROM city
        Mysql 学习(十 二)查询优化 Explain
    • UNION RESULT:MySQL选择使用临时表来完成UNION查询的去重工作,针对该临时表的查询的select_type就是UNION RESULT

      • 举个例子:EXPLAIN SELECT * FROM city UNION SELECT * FROM city
        Mysql 学习(十 二)查询优化 Explain
    • SUBQUERY:如果包含子查询的查询语句不能够转为对应的semi-join的形式,并且该子查询是不相关子查询,并且查询优化器决定采用将该子查询物化的方案来执行该子查询时,该子查询的第一个SELECT关键字代表的那个查询的select_type就是SUBQUERY

      • 举个例子:EXPLAIN SELECT * FROM city WHERE country_id IN (SELECT id FROM country ) OR postal_code = 1010
        Mysql 学习(十 二)查询优化 Explain
    • DEPENDENT SUBQUERY:如果包含子查询的查询语句不能够转为对应的semi-join的形式,并且该子查询是相关子查询,则该子查询的第一个SELECT关键字代表的那个查询的select_type就是DEPENDENT SUBQUERY

    • DEPENDENT UNION:在包含UNION或者UNION ALL的大查询中,如果各个小查询都依赖于外层查询的话,那除了最左边的那个小查询之外,其余的小查询的select_type的值就是DEPENDENT UNION

    • DERIVED:对于采用物化的方式执行的包含派生表的查询,该派生表对应的子查询的select_type就是DERIVED

    • MATERIALIZED:当查询优化器在执行包含子查询的语句时,选择将子查询物化之后与外层查询进行连接查询时,该子查询对应的select_type属性就是MATERIALIZED

    • UNCACHEABLE SUBQUERY

    • UNCACHEABLE UNION

partitions

  • 一般情况下我们的查询语句的执行计划的partitions列的值都是NULL。

type

  • 前几节我们知道查询是有访问方式,而在这里type字段就可以展示这个select语句是使用那种访问方式查询数据的
  • 类别:
    • system:当表中只有一条记录并且该表使用的存储引擎的统计数据是精确的,比如MyISAM、Memory,那么对该表的访问方法就是system

    • const:当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法就是const
      Mysql 学习(十 二)查询优化 Explain

    • eq_ref:在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则对该被驱动表的访问方法就是eq_ref
      Mysql 学习(十 二)查询优化 Explain

    • ref: 当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是ref

    • fulltext:全文索引

    • ref_or_null:当对普通二级索引进行等值匹配查询,该索引列的值也可以是NULL值时,那么对该表的访问方法就可能是ref_or_null

    • index_merge:一般情况下对于某个表的查询只能使用到一个索引,但我们介绍单表访问方法时特意强调了在某些场景下可以使用Intersection、Union、Sort-Union这三种索引合并的方式来执行查询

    • unique_subquery:类似于两表连接中被驱动表的eq_ref访问方法,unique_subquery是针对在一些包含IN子查询的查询语句中,如果查询优化器决定将IN子查询转换为EXISTS子查询,而且子查询可以使用到主键进行等值匹配的话,那么该子查询执行计划的type列的值就是unique_subquery

    • index_subquery:index_subquery与unique_subquery类似,只不过访问子查询中的表时使用的是普通的索引

    • range:如果使用索引获取某些范围区间的记录,那么就可能使用到range访问方法
      Mysql 学习(十 二)查询优化 Explain

    • index:当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是index

    • ALL:全表扫描文章来源地址https://www.toymoban.com/news/detail-448798.html

possible_keys

  • 在EXPLAIN语句输出的执行计划中,possible_keys列表示在某个查询语句中,对某个表执行单表查询时可能用到的索引有哪些
  • 比如下面这个例子,可能使用到的索引是idx_key1和idx_key3Mysql 学习(十 二)查询优化 Explain

key

  • 在EXPLAIN语句输出的执行计划中,possible_keys列表示在某个查询语句中,对某个表执行单表查询时实际用到的索引有哪些
  • 比如下面这个例子,使用到的索引是idx_key3Mysql 学习(十 二)查询优化 Explain

key_len

  • key_len列表示当优化器决定使用某个索引执行查询时,该索引记录的最大长度,它是由这三个部分构成的:
    • 对于使用固定长度类型的索引列来说,它实际占用的存储空间的最大长度就是该固定值,对于指定字符集的变长类型的索引列来说,比如某个索引列的类型是VARCHAR(100),使用的字符集是utf8,那么该列实际占用的最大存储空间就是100 × 3 = 300个字节。
    • 如果该索引列可以存储NULL值,则key_len比不可以存储NULL值时多1个字节
    • 对于变长字段来说,都会有2个字节的空间来存储该变长列的实际长度。

ref

  • 当使用索引列等值匹配的条件去执行查询时,也就是在访问方法是const、eq_ref、ref、ref_or_null、unique_subquery、index_subquery其中之一时,ref列展示的就是与索引列作等值匹配的东东是什么,比如只是一个常数或者是某个列

rows

  • 如果查询优化器决定使用全表扫描的方式对某个表执行查询时,执行计划的rows列就代表预计需要扫描的行数,如果使用索引来执行查询时,执行计划的rows列就代表预计扫描的索引记录行数。

filtered

  • 之前说连接查询的时候计算成本有扇出这个概念,而执行计划的filtered列就代表查询优化器预测rows列中的记录有多少条满足其余搜索条件,这里存的是百分比,比如下面:
    Mysql 学习(十 二)查询优化 Explain
  • 从执行计划中可以看出来,查询优化器打算把s1当作驱动表,s2当作被驱动表。我们可以看到驱动表s1表的执行计划的rows列为9688, filtered列为10.00,这意味着驱动表s1的扇出值就是9688 × 10.00% = 968.8,这说明还要对被驱动表执行大约968次查询。

Extra(待更新)

FORMAT=JSON 更加详细的执行计划(待更新)

optimizer trace(待更新)

到了这里,关于Mysql 学习(十 二)查询优化 Explain的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 玩转MySQL之SQL优化之EXPLAIN执行计划

    从今天开始本系列文章就带各位小伙伴学习数据库技术。 数据库技术是Java开发中必不可少的一部分知识内容。也是非常重要的技术。本系列教程由浅入深, 全面讲解数据库体系。 非常适合零基础的小伙伴来学习。 全文大约 【1965】字 ,不说废话,只讲可以让你学到技术、明

    2024年02月08日
    浏览(56)
  • 浅析MySQL代价模型:告别盲目使用EXPLAIN,提前预知索引优化策略

    在 MySQL 中,当我们为表创建了一个或多个索引后,通常需要在索引定义完成后,根据具体的数据情况执行 EXPLAIN 命令,才能观察到数据库实际使用哪个索引、是否使用索引。这使得我们在添加新索引之前,无法提前预知数据库是否能使用期望的索引。更为糟糕的是,有时甚至

    2024年02月05日
    浏览(52)
  • MySQL一条语句递归查询所有子集数据

    MySQL中,现有一组数据,数据包含字段主键:id,父类ID:pid,id与pid是继承关系,根据某个id查询其下级关联的所有记录; 1、利用递归查询语法。递归查询是在 MySQL 8.0 版本引入的新特性,如果您的 MySQL 版本低于 8.0,则无法使用递归查询语法。 在上面的语句中,使用了 Com

    2024年02月11日
    浏览(48)
  • MySQL 中一条 SQL 的查询与更新

      大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。   Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储

    2024年02月15日
    浏览(42)
  • MySQL—一条查询SQL语句的完整执行流程

    表结构和数据如下: 我们分析的sql语句如下: 大体来说,MySQL可以分为Server层和存储引擎层两部分: Server层 包括:连接器、查询缓存、分析器、优化器、执行器等 涵盖MySQL的大多数核心服务功能 所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在

    2024年04月28日
    浏览(64)
  • 从Mysql架构看一条查询sql的执行过程

    我们的程序或者工具要操作数据库,第一步要做什么事情? 跟数据库建立连接。 首先,MySQL必须要运行一个服务,监听默认的3306端口。在我们开发系统跟第三方对接的时候,必须要弄清楚的有两件事。 第一个就是通信协议,比如我们是用HTTP还是WebService还是TCP? 第二个是消

    2024年02月08日
    浏览(56)
  • myql进阶-一条查询sql在mysql的执行过程

    目录 1. 流程图 2. 各个过程 2.1 连接器 2.2 分析器 2.3 优化器 2.4 执行器 2.5 注意点 假设我们执行一条sql语句如下: 首先我们会和mysql建立连接,此时就会执行到连接器。 连接器的职责是负责和客户端建立连接、获取权限、维持和管理连接。 我们执行sql之前首先要和数据库建立

    2024年01月21日
    浏览(69)
  • MySQL索引3——Explain关键字和索引优化(SQL提示、索引失效、索引使用规则)

    目录 Explain 索引性能分析 Id ——select的查询序列号 Select_type——select查询的类型 Table——表名称 Type——select的连接类型 Possible_key ——显示可能应用在这张表的索引 Key——实际用到的索引 Key_len——实际索引使用到的字节数 Ref    ——索引命中的列或常量 Rows——预

    2024年02月14日
    浏览(57)
  • MYSQL实战45讲笔记--基础架构:一条SQL查询语句是如何执行的?

    MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层 :连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等

    2024年02月07日
    浏览(47)
  • Mysql一条多表关联SQL把CPU打爆了,如何优化

    今天是清明假期的第三天,收到同事的求助,DB的CPU被打爆了! 查看监控,CPU已经被打爆100% 登录mysql,DB无锁阻塞,元凶是一个异常sql,存在39个并发执行。 SQL的明细如下: select TEMPSALE.USER_ID_BUY,       TEMPSALE.ORDER_AMOUNT,       TEMPSALE.LAST_UPDATED_DATEfrom T_EAC_BU_SG_CO_INFO T

    2023年04月12日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包