当前位置: 首页 > news >正文

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(执行计划)详解

相关文章:

Mysql explain 优化解析

explain 解释 select_type 效率对比 MySQL 中 EXPLAIN 语句的 select_type 列描述了查询的类型,不同的 select_type 类型在效率上会有所差异。下面我们来比较一下各种 select_type 的效率: SIMPLE: 这是最简单的查询类型,表示查询不包含子查询或 UNION 操作。 这种查询通常是…...

wget下载github文件得到html文件

从github/gitee下载源文件,本来是22M下载下来只有11k 原因: Github会提供html页面,包括指定的文件、上下文与相关操作。通过wget或者curl下载时,会下载该页面 解决方式: github点击Code一栏的raw按钮,获得源…...

【es】elasticsearch 自定义排序-按关键字位置排序

一 背景 要求es查询的结果按关键字位置排序,位置越靠前优先级越高。 es版本7.14.0,项目是thrift,也可以平替springboot,使用easyes连接es。 二 easyes使用 配easyes按官方文档就差不多了 排序 | Easy-Es 主要的一个问题是easy…...

堆的相关知识点

目录 大小堆 堆的实现 堆的创建 堆的销毁 交换 向上调整 向下调整 弹出首个元素 取出首个元素 判空 堆插入 大小堆 大堆:最上面的数字是最小的,越往下越大 小堆:最上面的数字是最大的,越往下越小 堆的复杂程度&#…...

【Sass】常用全局sass高级函数,可使用原子化CSS减轻代码量,方便快速开发

文章目录 前言一、安装二、样式custom.scssflex.scsscolor.scssmargin-padding.scssorther 总结 前言 提示:这里可以添加本文要记录的大概内容: 针对style的预编译器为scss 转载自git前端知识库 原博主是B站up程序员郑清,可以看他的v3教程…...

MYSQL 第四次作业

任务要求: 具体操作: 新建数据库: mysql> CREATE DATABASE mydb15_indexstu; Query OK, 1 row affected (0.01 sec) mysql> USE mydb15_indexstu; Database changed 新建表: mysql> CREATE TABLE student( ->…...

depcheck 前端依赖检查

介绍 depcheck 是一款用于检测项目中 未使用依赖项 的工具。 depcheck 通过扫描项目文件,帮助你找出未被引用的依赖,从而优化项目。 优势: 简单易用: 仅需几个简单的命令,就能够扫描并列出未使用的依赖项,让你快速了…...

Qt/C++音视频开发79-采集websocket视频流/打开ws开头的地址/音视频同步/保存到MP4文件/视频回放

一、前言 随着音视频的爆发式的增长,各种推拉流应用场景应运而生,基本上都要求各个端都能查看实时视频流,比如PC端、手机端、网页端,在网页端用websocket来接收并解码实时视频流显示,是一个非常常规的场景,单纯的http-flv模式受限于最大6个通道同时显示,一般会选择ws-f…...

网络安全等级保护制度1.0与2.0的演进与变革

等保1.0概述 等保1.0是我国在网络安全领域迈出的重要一步,它于2008年正式发布。该版本的等保制度以《信息安全技术 信息系统安全等级保护基本要求》为核心标准,主要聚焦于信息系统的物理安全、网络安全、主机安全、应用安全和数据安全等方面的基础防护。…...

多线程优化API请求:CountDownLatch与PriorityBlockingQueue的应用

目录 前言 CountDownLatch是什么? PriorityBlockingQueue是什么? 场景描述 解决方案 定义统一工厂制造类 定义制造厂 定义客户请求实现 定义控制器 定义启动类 结果呈现 启动项目 请求制造操作 总结 前言 写这篇文章的缘由是因为之前在面…...

谷粒商城实战笔记-54-商品服务-API-三级分类-拖拽效果

文章目录 一,54-商品服务-API-三级分类-修改-拖拽效果1,el-tree控件加上允许拖拽的属性2,是否允许拖拽3,完整代码 一,54-商品服务-API-三级分类-修改-拖拽效果 本节的主要内容是给三级分类树形结构加上拖拽功能&#…...

AI大模型学习必备十大网站

随着人工智能技术的快速发展,AI大模型(如GPT-3、BERT等)在自然语言处理、计算机视觉等领域取得了显著的成果。对于希望深入学习AI大模型的开发者和研究者来说,找到合适的学习资源至关重要。本文将为大家推荐十大必备网站&#xff…...

Elasticsearch:Golang ECS 日志记录 - zap

ECS 记录器是你最喜欢的日志库的格式化程序/编码器插件。它们可让你轻松地将日志格式化为与 ECS 兼容的 JSON。 编码器以 JSON 格式记录日志,并在可能的情况下依赖默认的 zapcore/json_encoder。它还处理 ECS 错误格式的错误字段记录。 默认情况下,会添…...

关于线性代数(考研)

1.AE的特征值的问题 若λ是A的特征值,对应的特征向量是x,则Axλx,所以(AE)xAxExλxx(λ1)x,所以λ1是AE的特征值。所以若A的特征值是1,1,0,则AE的特征值就是11,11,01&am…...

【java基础】spring springMVC springboot 的区别

Spring, Spring MVC, 和 Spring Boot 是三个紧密相关的技术,它们都是由 Pivotal 团队(原SpringSource)开发的,主要用于构建企业级的Java应用程序。尽管它们在功能上有所交集,但各自也有独特的定位和用途。 Spring Fra…...

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 开源项目热度排行榜(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆Coding ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线评测,专栏文章质量平均 93 分 最新华为OD机试目录…...

大模型算法面试题(十一)

本系列收纳各种大模型面试题及答案。 1、说一下目前主流或前沿的预训练模型,包括nlp(百度ERNIE3.0,华为NEZHA,openAI gpt-3,nvidia MegatronLM,macrosoft T5)和cv(我只知道CLIP&…...

CSS 基础知识

CSS(级联样式表)是设置 Web 内容样式的代码。CSS 基础知识将介绍入门所需的内容。我们将回答以下问题:如何将文本设置为红色?如何使内容显示在(网页)布局中的某个位置?如何用背景图片和颜色装饰我的网页? 什么是CSS? 像HTML一样,CSS不是一种编程语言。它也不是一种标…...

IntelliJ IDEA 和 Eclipse的区别

IntelliJ IDEA 和 Eclipse 是两个非常流行的 Java 集成开发环境(IDE),它们各自具有不同的特点和优势。下面是它们之间的一些主要对比: 性能和资源使用 IntelliJ IDEA 被认为在某些方面更加智能,能够提供更好的代码分…...

Ansible之playbook剧本编写(二)

tags 模块 可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。 playbook还提供了一个特殊的tags为always。作用就是当使用always作为tags的task时,无论执行哪一个t…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...