又是一条慢 SQL 改写,拿捏!

作者分享了一条慢 SQL 分析和优化的过程,总结出切实有效的优化手段。

作者:马文斌

MySQL 爱好者。

本文来源:原创投稿

  • 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

背景

开发同学丢了一条 SQL 过来。“马哥,看看这个 SQL 能否优化,业务那边反馈很慢!”看了下执行计划+表结构,索引都没问题。那到底是怎么回事呢?咱们一起来瞧瞧。

分析原 SQL

explain SELECTcount(0)
FROMinvoice_sales_application a
WHERE(shop_order_id LIKE '23060919546335%'OR (EXISTS (SELECT1FROMinvoice_sales_application_detail bWHEREa.application_no = b.application_noAND a.invoice_category = b.invoice_categoryAND b.del_flag = 0AND b.shop_order_id LIKE '23060919546335%')AND a.is_merge = 1))

先来看看这个 SQL 是什么意思:

invoice_sales_application 表中,shop_order_id'23060919546335%'开头,或者存在一个相关的 invoice_sales_application_detail 表中的记录,该记录的 application_noinvoice_categoryinvoice_sales_application 表中的相同,并且 shop_order_id'23060919546335%' 开头,同时 invoice_sales_application 表中的 is_merge 字段为 1

执行计划:all+ref,其中 a 表要扫描 116w 行的数据。

执行计划

执行需要 43s,且有一个全表扫描。

扫描时间

优化操作

EXISTS 转化成 JOIN 的方式

这里是把 EXISTS 改写成 INNER JOIN 通过索引关键关联,应该会有不错的效果,试试看。

SELECT  count(0)
FROM invoice_sales_application a INNER
JOIN invoice_sales_application_detail bON a.application_no = b.application_no
WHERE ( a.shop_order_id LIKE '23060919546335%'OR ( b.shop_order_id LIKE '23060919546335%'AND a.is_merge = 1 ) )AND a.invoice_category = b.invoice_categoryAND b.del_flag = 0

执行效果

这里虽然转化了 INNER JOIN 的方式,执行计划还是 all+ref ,因为用了 OR 导致 a 表没有用上索引,还是用的全表扫描。没关系,咱们再次进行转化。

OR 改成 UNION

 SELECT count(*)FROM invoice_sales_application aINNER JOIN invoice_sales_application_detail b ON a.application_no = b.application_noAND a.invoice_category = b.invoice_categoryAND b.del_flag = 0WHERE a.shop_order_id = '23060919546335'AND a.del_flag = 0UNIONSELECT count(*)FROM invoice_sales_application aINNER JOIN invoice_sales_application_detail b ON a.application_no = b.application_noAND a.invoice_category = b.invoice_categoryAND b.del_flag = 0WHERE b.shop_order_id = '23060919546335'AND a.is_merge = 1AND a.del_flag = 0;

在看看执行计划,eq_ref+ref+ref+ref。说明已经优化的很好了,起码没有全表扫描。

执行计划

最后看看结果。

执行计划

这样 SQL 执行很快了,查询时间从 42s 降到 18ms,快了几个数量级。

小结

1、当 SQL 的主架构中含有 EXISTS 的时候,可以改成 INNER JOIN 的方式,先看看效果。

2、当条件中有 OR 的时候,可以改成 UNION 试试。

关于 SQLE

爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。

SQLE 获取

类型地址
版本库https://github.com/actiontech/sqle
文档https://actiontech.github.io/sqle-docs/
发布信息https://github.com/actiontech/sqle/releases
数据审核插件开发文档https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_development.html

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

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

相关文章

※Redis的事务、乐观锁和悲观锁

1.是神魔 在高并发的环境下,多个线程去竞争同一个资源, 比较常见的有高铁抢票系统,商品秒杀系统等,我们需要保证数据正确,同时系统的吞吐也要尽可能高。2.解决方案 1. 一般多线程同步我们就会想到加锁,用…

数据库作业——select查询操作

数据库作业 创建数据库 mysql> create table worker( -> 部门号 int(11) not null, -> 职工号 int(11) primary key not null,-> 工作时间 date not null,-> 工资…

MiniGPT4 在RTX-3090 Ubuntu服务器部署步骤详解

主要参考知乎帖子: MiniGPT-4 本地部署 RTX 3090 - 知乎 MiniGPT-4部署比麻烦,首先需要获取LLaMA权重,并结合Vicuna的bitwise XOR增量文件完成Vicuna模型权重生成,最后准备好预训练的MiniGPT-4进行模型部署。为了便于理解&#…

这3个方法教你录音转文字怎么导出来

在日常生活中,我们有时候可能需要将音频转换为文本,因为这样可以节省我们听的时间,还能让记录更加清楚明了。那么,你是否知道录音转文字怎么导出来?如果你不懂,请接着看我下面介绍的三种方法吧!…

pytorch安装问题【超级简单版】

pytorch安装问题 当前遇到的问题: python3.9无法安装读取coco数据集的 pycocotools-windows,那么需要切换版本到3.6/7/8,但是切换到python 3.6之后,无法安装torchvision和pytorch【在python就叫torch】,显示没有这个版本 pip i…

[RocketMQ] Broker 消息重放服务源码解析 (十三)

构建消息文件ConsumeQueue和IndexFile。 ConsumeQueue: 看作是CommitLog的消息偏移量索引文件, 存储了它所属Topic的消息在Commit Log中的偏移量。消费者拉取消息的时候, 可以从Consume Queue中快速的根据偏移量定位消息在Commit Log中的位置。IndexFile索引文件: 看作是Commi…

UE4 像素流的一些使用技巧

一、测试像素流的三种方法,前提是熟悉官网像素流送那套流程,这里只是讲如何不用打包就能测试的方法 1.第一种方法是vs安装unrealvs扩展,因为安装这个拓展后加可以加命令行参数启动项目https://docs.unrealengine.com/4.26/zh-CN/ProductionP…

怎么用PDF24 Tools工具在线进行PDF文件合并

PDF文件是经常会被用到,它在我们的日常生活和工作中扮演着重要的角色。PDF文件合并是将多个PDF文件合并为单个文件,这个过程通常是为了方便管理多个PDF文件,或者将多个PDF文件合并为一个整体以便于共享或打印。既然如此,如何快速合…

Spring5学习笔记--详细一文通

Spring5学习笔记--详细一文通 1 Spring 框架概述1.1 Spring 5 简述1.2 Spring5入门案例1.2.1 Spring5下载1.1.2 打开 idea 工具,创建普通 Java 工程1.2.3 导入 Spring5 相关 jar 包1.2.4 创建普通类,在这个类创建普通方法1.2.5 创建 Spring 配置文件&…

迅捷录屏软件使用中的注意事项

取消勾选时就不会出现右侧的悬浮框滑动的窗口了。 取消鼠标高亮后,录制的视频就不会出现一个空心的小圆圈。

实战解决百度旋转验证码

1、效果演示 2、如何识别 2.1准备数据集 首先需要使用爬虫,对验证码图片进行采集,尽量每一种类型都要采集到。 2.2图像矫正 接下来对采集的数据进行人工校正 2.3数据清洗 (1)对数据进行进行旋转,达到增加数据量的目…

ubuntu RPM should not be used directly install RPM packages, use Alien instead!

ubuntu RPM should not be used directly install RPM packages, use Alien instead! 所以我们最好下载deb版本的安装包 安装 参考文章