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,一经查实,立即删除!

相关文章

iOS ------ 关键字

关键字可以分为以下六类 修饰器类型:property、synthesize、dynamic原子安全类型: nonatomic、atomic计数引用类型: strong、weak、assign、copy、retain、unsafe_unretained读写类型:readonly,readwrite访问类型:extern、static、const局部…

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

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

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

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

数据集,批量更新分类数值OR批量删除分类行数据

数据集批量更新分类OR删除分类行数据 import osdef remove_class_from_file(file_path, class_to_remove):"""从YOLO格式的标注文件中删除指定类别的行记录,并去除空行。:param file_path: YOLO标注文件路径:param class_to_remove: 需要删除的类别…

linux中的目录操作函数

参考 【Linux系统编程】Linux 文件系统探究:深入理解 struct dirent、DIR 和 struct stat结构 stat函数 C标准库提供了访问linux的目录的函数接口现对目录的操作。 一、libc接口 libc访问目录的流程为:打开目录,访问目录,关闭目…

uniapp 小程序 支付逻辑处理

uniapp 小程序 支付逻辑处理 上代码如果你不需要支付宝适配&#xff0c;可以删除掉支付宝的条件判断代码 <button class"subBtn" :disabled"submiting" click"goPay">去支付</button>// 以下代码你需要改的地方// 1. order/app/v1…

怎样实现大语言模型微调,庞氏骗局智能合约检查,BERT

目录 怎样实现大语言模型微调 一、了解微调的基本概念 二、选择合适的微调方法 三、实施微调的具体步骤 四、注意事项 庞氏骗局智能合约检查 一、使用的大模型 二、微调方法 1. 数据准备 2. 微调策略 3. 微调过程 三、输入和输出 输入 输出 四、注意事项 一、使…

【Linux】centos7安装php7.4

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

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

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

【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规范定义了三种类型的消息: •简短的控制消息&#xff0c;用于管理端口伙伴之间的消息流或交换不需要额外数据的消息。控制消息的长度为16位。 •用于在一对端口伙伴之间交换信息的数据消息。数据报文的长度范围是48 ~ 240位。 有三种类型的数据消息: ▪那些用于暴露…

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

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

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

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

智能路面裂缝检测:基于YOLO和深度学习的全流程实现

引言 路面裂缝检测是维护道路质量和延长道路寿命的重要手段。传统的检测方法往往费时费力且易受人为因素影响。为了提高检测效率和准确性&#xff0c;本文介绍了一种基于深度学习的路面裂缝检测系统。该系统包括用户界面&#xff0c;利用YOLO&#xff08;You Only Look Once&a…

Typescript学习笔记(1.0)

1.ts开发环境&#xff1a;先安装Node&#xff0c;然后执行命令npm i -g typescript,这里使用的是npm命令&#xff0c;也可以使用pnpm和yarn安装&#xff0c;不过需要额外安装pnpm 和yarn。 2.第一个一ts为后缀的文件&#xff0c;使用命令&#xff1a; tsc *.ts 就会生成对应…

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

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

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

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

学习React(状态管理)

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

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

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

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

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