Mysql explain 优化解析

explain 解释

在这里插入图片描述

select_type 效率对比

MySQL 中 EXPLAIN 语句的 select_type 列描述了查询的类型,不同的 select_type 类型在效率上会有所差异。下面我们来比较一下各种 select_type 的效率:

  1. SIMPLE:
    这是最简单的查询类型,表示查询不包含子查询或 UNION 操作。
    这种查询通常是最高效的,因为 MySQL 可以更好地优化执行计划。
    当查询只涉及一个表时,select_type 就会显示为 SIMPLE。

explain select * from user where uid=1;
在这里插入图片描述

  1. PRIMARY:
    这种查询类型表示最外层的查询。
    与 SIMPLE 类型相比,它可能会稍微低效一些,因为可能包含子查询。
    当查询中包含子查询时,子查询的 select_type 会显示为 SUBQUERY。

explain select * from (select * from user where uid=1)b
在这里插入图片描述

  1. SUBQUERY:
    这种查询类型表示作为独立子查询执行的查询块。
    子查询的效率通常比外层查询低,因为它需要单独执行并返回结果。
    子查询可能会在外层查询中多次使用,每次都需要重新执行,因此效率较低。

explain select * from groups where gid =(select gid from user where uid=1)
在这里插入图片描述

  1. DERIVED:
    这种查询类型表示从 FROM 子句的结果集中派生出来的临时表。
    这种查询通常比较低效,因为需要在查询执行时动态计算临时表。
    使用临时表可能会导致 MySQL 使用 Using temporary; Using filesort 策略,从而降低查询效率。

explain select * from (select * from user where uid=1)b
在这里插入图片描述

  1. UNION:
    这种查询类型表示 UNION 操作,用于合并多个查询结果集。
    UNION 操作通常比较低效,因为需要合并多个结果集。
    如果 UNION 中的子查询可以独立执行,可以考虑将它们拆分成多个查询,然后在代码中进行合并。

explain select * from user where uid=1 union select * from user where uid=2
在这里插入图片描述

  1. DEPENDENT UNION
    依赖性(DEPENDENT): 这个子查询依赖于外层查询的结果。也就是说,子查询的执行需要依赖外层查询的结果。
    DEPENDENT UNION(从属联合)与DEPENDENT SUBQUERY(依赖子查询):
    当union作为子查询时,其中第二个union的select_type就是DEPENDENT UNION。第一个子查询的select_type则是DEPENDENT SUBQUERY。

在这里插入图片描述

  1. UNION RESULT:
    这种查询类型表示 UNION 操作的结果。
    这种查询通常是最低效的,因为需要额外的合并操作。
    如果可以,尽量避免使用 UNION。

explain select * from user where uid=1 union select * from user where uid=2
在这里插入图片描述

总的来说,效率从高到低的顺序是:

SIMPLE > PRIMARY > SUBQUERY > DERIVED > UNION > DEPENDENT UNION > UNION RESULT

当然,实际的效率还受到其他因素的影响,如表的大小、索引情况、查询条件等。因此在实际使用中,我们还需要通过 EXPLAIN 语句分析具体的查询计划,并根据结果进行针对性的优化。

同时,也要注意查询的语义和可读性。有时为了提高效率,可能需要牺牲一些查询的可读性,这需要权衡取舍。

总之,在优化 MySQL 查询时,不仅要关注 select_type 的效率,还要综合考虑其他因素,并进行适当的优化。

type 列

TYPE含义解释

在这里插入图片描述

TYPE效率对比

MySQL 中 EXPLAIN 语句的 type 列描述了表访问的类型,这个列的值可以反映查询的效率。以下是 type 列各个值的含义:
好的,那我们再深入探讨一下 MySQL 中 EXPLAIN 语句的 type 列各个值的更多细节:

  1. system:
    这是一种特殊的 const 类型,表示表中只有一条记录。
    这种类型的访问速度是最快的,因为只需要读取一条记录。
    通常出现在使用常量表的查询中,比如使用 LIMIT 1 的查询。
  2. const:
    当查询能够在查询一次后就确定结果时,表示"constant"。
    典型的例子是当查询的 WHERE 子句使用主键或唯一索引时,MySQL 能在查询一次之后就确定结果。
    这种访问类型的速度非常快,因为它只需要读取一次记录。
  3. eq_ref:
    当查询使用主键或唯一索引时,对于每个索引键,表中只有一条记录与之匹配。
    这种访问类型的效率仅次于 const,是一种非常高效的访问方式。
    常见于多表连接中根据主键或唯一索引列进行关联的情况。
  4. ref:
    当查询使用非唯一索引或者触发了部分索引列(比如最左前缀)时,返回匹配某个单值的所有行。
    这种访问类型的效率略低于 eq_ref,但仍然较为高效。
    常见于使用非唯一索引进行关联查询的情况。
  5. range:
    当使用索引来检索某个范围的记录时,该访问类型就会被使用。
    比如 WHERE col BETWEEN 10 AND 20 或 WHERE col IN (10, 20, 30)。
    这种访问方式需要检索索引中的部分键值,因此效率比 ref 稍低。
  6. index:
    当 MySQL 决定全表扫描要比使用等值或范围索引快时, 并且索引覆盖所需要的列(包括在查询和条件中)时,使用索引树来遍历数据。
    这种方式虽然比全表扫描快,但比使用传统的索引扫描慢。
    通常出现在查询的 WHERE 子句未能有效利用索引的情况。
  7. ALL:
    这是最差的访问类型,表示需要进行完整的表扫描。
    通常情况下,应该尽量避免查询出现这种访问类型。
    如果出现这种情况,通常意味着需要为相关列创建索引来优化查询。

总的来说,type 列的取值越往后,查询的效率就越低。提高查询效率的一个重要方法,就是尽量使用更高效的访问类型,如const、eq_ref、ref等。一般来说,至少保证查询达到range级别,最好达到ref。这需要为相关列建立合适的索引,并根据查询的条件进行针对性的优化。

实例分析

调优思路

  • 拆分sql,并发查询出符合标签的group_id, 效果不理想
  • 干掉多余的subquery,有效果
  • in转换成join,效果不理想,跟数据量、数据分布、索引情况都有关系
    • 当数据量巨大(百万以上)、且数据散列分布均匀时,此时应该采用join
    • 大数据量不大或者数据分布聚集时,此时in效率更好
  • 减少子查询,减少派生临时表,效果立竿见影

优化前后对比

优化前:

SELECT t1.*,t2.*
FROM(SELECT a.*FROM syyy_dest aWHERE a.del_flag = 0AND a.id IN(SELECT t3.group_idFROM(SELECT group_id,group_concat(tag_id)AS tag_idsFROM syyy_group_tagWHERE delete_flag = 0AND tag_id IN ('123')GROUP BY group_idHAVING find_in_set('123', tag_ids)) t3) ) t1
LEFT JOIN(SELECT group_id,group_concat(category_name, ':', tag_name) AS tagNameFROM syyy_group_tag gtLEFT JOIN syyy_tag c ON gt.tag_id = c.idLEFT JOIN syyy_tag_category stc ON c.tag_category_id = stc.idWHERE gt.delete_flag = 0GROUP BY group_id) t2 ON t1.id = t2.group_id
ORDER BY t1.id DESC
LIMIT 10;

优化前查询结果:
在这里插入图片描述

优化后:

SELECTa.*,gt.group_id,group_concat(stc.category_name, ':', c.tag_name) as tagNameFROM  syyy_dest aLEFT JOIN (SELECT group_id, tag_id FROM syyy_group_tag WHERE delete_flag = 0) gtON a.id = gt.group_idLEFT JOIN syyy_tag cON gt.tag_id = c.idLEFT JOIN syyy_tag_category stcON c.tag_category_id  = stc.idWHERE a.del_flag = 0         and a.id in(select t3.group_id from(select group_id , group_concat(tag_id)as tag_ids from syyy_group_tagwhere delete_flag = 0and tag_id in(  123) group by group_idhavingfind_in_set( 123, tag_ids)) t3 where 1=1) GROUP BY a.idorder by a.id desc LIMIT 10

优化后查询结果:在这里插入图片描述

减少派生临时表字查询的优化分析

因为需要在查询执行时动态计算临时表,因此这种查询通常比较低效

优化前

explain
SELECT t1.*,t2.tag_name
FROM(SELECT a.*FROM syyy_dest aWHERE a.del_flag = 0 ) t1
LEFT JOIN(SELECT group_id,group_concat(category_name, ':', tag_name) AS tag_nameFROM syyy_group_tag gtLEFT JOIN syyy_tag c ON gt.tag_id = c.idLEFT JOIN syyy_tag_category stc ON c.tag_category_id = stc.idWHERE gt.delete_flag = 0GROUP BY group_id) t2 ON t1.id = t2.group_id
ORDER BY t1.id DESC

执行计划:
在这里插入图片描述

优化后

explain
SELECTa.*,group_concat(stc.category_name, ':', c.tag_name) as tag_nameFROM  syyy_dest aLEFT JOIN (SELECT group_id, tag_id FROM syyy_group_tag WHERE delete_flag = 0) gtON a.id = gt.group_idLEFT JOIN syyy_tag cON gt.tag_id = c.idLEFT JOIN syyy_tag_category stcON c.tag_category_id  = stc.idWHERE a.del_flag = 0
GROUP BY a.id
ORDER BY a.id desc

执行计划:
在这里插入图片描述

优化分析:

  1. 优化后减少了一次子查询,减少了派生临时表的生成

  2. select_type优化后为smiple,性能最优

  3. 优化后连接类型type,c和stc表为eq_ref,因为使用了主键连接;syyy_group_tag为ref,因为虽然使用了唯一建,但是只是触发了部分索引列(最左前缀),因此连接方式不是eq_ref, 如下:
    在这里插入图片描述

  4. 优化后a表的连接类型依旧为index,扫描整个索引树,这种访问方式比全表扫描快,但相比使用其他索引访问方式(如 ref、eq_ref 等)仍然较慢。是因为连接条件a.del_flag = 0的数据离散度较小,数据分布极不均匀(只有0和1),所以mysql引擎优化的结果是不使用索引的等值查找(ref),即使存在del_flag字段的索引,如下:
    在这里插入图片描述

参考

MySQL Explain(执行计划)详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/49201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot集成Spire.doc实现对word的操作

1.什么是spire.doc? Spire.Doc for Java 是一款专业的 Java Word 组件,开发人员使用它可以轻松地将 Word 文档创建、读取、编辑、转换和打印等功能集成到自己的 Java 应用程序中。作为一款完全独立的组件,Spire.Doc for Java 的运行环境无需安装 Micro…

【stm32项目】基于stm32智能宠物喂养(完整工程资料源码)

基于STM32宠物喂养系统 前言: 随着人们生活幸福指数的提高,越来越多的家庭选择养宠物来为生活增添乐趣。然而,由于工作等原因,许多主人无法及时为宠物提供充足的食物与水。为了解决这一问题,我设计了一款便捷的宠物喂…

【Linux】centos7安装php7.4

环境说明 本文档在服务器不能连接互联网的情况下,进行安装php7.4及其扩展。 操作系统:centos7.6 架构:X86_64 一、安装依赖(可选) 说明:服务器能联网就可以通过 yum install 命令下载对应php需要的依赖…

设计模式之策略模式_入门

前言 最近接触了优惠券相关的业务,如果是以前,我第一时间想到的就是if_else开始套,这样的话耦合度太高了,如果后期添加或者删除优惠券,必须直接修改业务代码,不符合开闭原则,这时候就可以选择我…

【TypeScript 一点点教程】

文章目录 一、开发环境搭建二、基本类型2.1 类型声明2.2 基本类型 三、编译3.1 tsc命令3.2 tsconfig.json3.2.1 基本配置项includeexcludeextendsfiles 3.2.2 compilerOptions编译器的配置项 四、面向对象4.1 类4.2 继承4.3 抽象类4.4 接口 一、开发环境搭建 下载Node.js《Nod…

usb pd message结构解析

usb pd 3.1规范定义了三种类型的消息: •简短的控制消息,用于管理端口伙伴之间的消息流或交换不需要额外数据的消息。控制消息的长度为16位。 •用于在一对端口伙伴之间交换信息的数据消息。数据报文的长度范围是48 ~ 240位。 有三种类型的数据消息: ▪那些用于暴露…

【区块链+绿色低碳】双碳数字化管控平台 | FISCO BCOS应用案例

地方政府、园区及企业实现“双碳”目标过程中存在一些挑战与难点: 1. 管理者难以掌握完整、准确、全面的碳排放数据进行科学决策:由于碳排放核算需要对数据的来源、核算方法 的规范性和采集方法的科学性有严格要求,当前面临碳排放数据数据采…

中国一汽发布“一汽●北斗云工作台” 意在推动企业数智化转型

“一汽●北斗云工作台”已经实现100%自主可控,覆盖企业全价值链、全体系、全过程、全岗位的工作需求。目前一汽2.3万个业务单元实现线上作业,产品开发效率提升30%,订单交付周期缩短25%以上。”7月17日,中国第一汽车集团有限公司&a…

electron 网页TodoList工具打包成win桌面应用exe

参考: electron安装(支持win、mac、linux桌面应用) https://blog.csdn.net/weixin_42357472/article/details/140643624 TodoList工具 https://blog.csdn.net/weixin_42357472/article/details/140618446 electron打包过程: 要将…

【吊打面试官系列-ZooKeeper面试题】Zookeeper 的典型应用场景

​大家好,我是锋哥。今天分享关于 【Zookeeper 的典型应用场景 】面试题,希望对大家有帮助; Zookeeper 的典型应用场景 Zookeeper 是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员可以使用它来进行分布式数据的发布…

学习React(状态管理)

随着你的应用不断变大,更有意识的去关注应用状态如何组织,以及数据如何在组件之间流动会对你很有帮助。冗余或重复的状态往往是缺陷的根源。在本节中,你将学习如何组织好状态,如何保持状态更新逻辑的可维护性,以及如何…

基于自组织映射的检索增强生成

大量数据用于训练大型语言模型 (LLM),该模型包含数百万和数十亿个模型参数,目的是生成文本,例如文本补全、文本摘要、语言翻译和回答问题。虽然 LLM 从训练数据源中开发知识库,但总有一个训练截止日期,在此日期之后 LL…

java jts 针对shp含洞多边形进行三角剖分切分成可行区域

前言 java jts 提供了Delaunay三角剖分的相关方法,但是该方法不考虑含洞的多边形的。虽然 jts 的 ConformingDelaunayTriangulationBuilder 类可以通过提供线段约束的方式防止切割到洞内,但是仅支持最多99条线段,虽然可以通过重写破除99条线段的约束&am…

Java——————接口(interface) <详解>

1.1 接口的概念 在现实生活中,接口的例子比比皆是,比如:笔记本电脑上的USB接口,电源插座等。 电脑的USB口上,可以插:U盘、鼠标、键盘...所有符合USB协议的设备 电源插座插孔上,可以插&#xff…

OS Copilot初体验的感受与心得

本文介绍体验操作系统智能助手OS Copilot后,个人的一些收获、体验等。 最近,抽空体验了阿里云的操作系统智能助手OS Copilot,在这里记录一下心得与收获。总体观之,从个人角度来说,感觉这个OS Copilot确实抓住了不少开发…

EasyMedia转码rtsp视频流flv格式,hls格式,H5页面播放flv流视频

EasyMedia转码rtsp视频流flv格式,hls格式 H5页面播放flv流视频 文章最后有源码地址 解决海康视频播放视频流,先转码后自定义页面播放flv视频流 先看效果,1,EasyMedia自带的页面,这个页面二次开发改动页面比较麻烦 …

张高兴的 MicroPython 入门指南:(三)使用串口通信

目录 什么是串口使用方法使用板载串口相互通信 硬件需求电路代码使用板载的 USB 串口参考 什么是串口 串口是串行接口的简称,这是一个非常大的概念,在嵌入式中串口通常指 UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)。…

初识c++(string和模拟实现string)

一、标准库中的string类 string类的文档介绍:cplusplus.com/reference/string/string/?kwstring 1、auto和范围for auto: 在早期C/C中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个 不重…

Cannot perform upm operation: connect ETIMEDOUT 34.36.199.114:443 [NotFound]

版本:Unity 2018 Windows 问题:打开 Package Manager,加载报错 尝试解决: 删除项目文件里的Packages下的mainfest.json文件,然后重新打开项目(X)重新登录 Unity 账号(X&#xff09…

Kotlin 协程 — 基础

Kotlin 协程 — 基础 协程已经存在一段时间了,关于它的各种文章也很多。但我发现想要了解它还比较费时,所以我花了一段时间才真正理解了协程的基础知识以及它的工作原理。因此,我想分享一些我理解到的内容。 什么是协程? 协程代表…