生产上的一次慢查询SQL优化

news2024/11/15 5:08:59

一、背景

MySQL版本5.6.16,InnoDB
生产上有个业务场景,需要每日拉取还款计划表里某些产品编号的所有状态为0,1数据的借据号和产品编号,SQL如下

select distinct
        loan_no,product_code
        from repay_plan
        <where>
            status in ('0','1') --状态
            and gmt_created >=#{condition.startDate,jdbcType=TIMESTAMP} --创建时间
            and gmt_created <=#{condition.endDate,jdbcType=TIMESTAMP}
            and product_code in
            <foreach item="productCode" collection="condition.productCodes" index="index" open="(" separator=","
                     close=")">
                #{productCode,jdbcType=VARCHAR} --产品编号
            </foreach>
        </where>
        order by gmt_created asc
        LIMIT #{condition.offset}, #{condition.limit}

repay_plan单表,数据量1500w,已有普通索引

  KEY `idx_product_code` (`product_code`) USING BTREE,
  KEY `idx_gmt_created` (`gmt_created`) USING BTREE,

product_code是一个枚举,SQL中in条件几乎包含了所有的枚举值

上线后发现任务执行缓慢

二、问题排查

通过日志观察发现大概率是SQL慢查询问题,进行慢查询追踪,成功找到这条SQL

在这里插入图片描述
很明显查了全表,一次SELECT耗时700+s,rds监控也印证了问题,在执行时间内打满了IO
在这里插入图片描述
在生产环境Explain分析SQL执行计划
在这里插入图片描述
发现SQL优化器在product_code和gmt_created两个索引中选择了product_code,但我们知道product_code中包含了几乎所有枚举值,此时选择走product_code与不使用索引无异。应使用gmt_created索引。

在测试环境中模拟生产环境,脚本随机生成80w条数据,执行explain和sql,问题复现。

三、优化

到此我们已经清楚SQL慢查询发生的原因:
1.SQL优化器索引选择错误,导致扫描全表
2.limit的offset过大导致IO效率低下,IO被打满

优化后SQL如下,通过强制指定索引减少扫描行数,使用主键索引访问数据块提升IO效率

SELECT DISTINCT loan_no, product_code
        FROM repay_plan
        INNER JOIN (
        SELECT id
        FROM repay_plan force index (idx_gmt_created)
        <where>
            status in ('0','1')
            and gmt_created &gt;=#{condition.startDate,jdbcType=TIMESTAMP}
            and gmt_created &lt;=#{condition.endDate,jdbcType=TIMESTAMP}
            and product_code in
            <foreach item="productCode" collection="condition.productCodes" index="index" open="(" separator=","
                     close=")">
                #{productCode,jdbcType=VARCHAR}
            </foreach>
        </where>
        order by gmt_created asc
        LIMIT #{condition.offset}, #{condition.limit}
        ) `tmp_0` USING (`id`)

优化后观察监控,SQL执行时间降低至1s内,IO使用率正常

四、总结

1.MySQL优化器虽然这次出了问题,但它依然值得信赖,非特殊情况不要强制指定SQL优化,MySQL优化器比我们更懂SQL。
2.由于InnoDB索引的特性,使用limit要注意offset过大导致的性能问题,即offset过大,多次通过主键索引访问数据块的I/O操作。解决办法是在找到主键索引后,先执行offset偏移处理,跳过{offset}条,再通过第{offset}+1条记录的主键索引去读取数据块。

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

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

相关文章

银行数字化转型导师坚鹏:银行业务数字化创新工作坊(简版)

银行业务数字化创新工作坊&#xff08;简版&#xff09; 课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不清楚如何进行业务数字化创新&#xff1f; 不知道如何开展银行数字化营销工作&#xff1f; 不知道零售业务数字化创新成功案例&#xff1f; 学员收获&a…

Filter 过滤器--基本原理--Filter 过滤器生命周期--过滤器链--注意事项和细节--全部应用实例--综合代码示例

目录 Filter 过滤器 Filter 过滤器说明 过滤器介绍 4. 应用场景 Filter 过滤器基本原理 代码示例 login.jsp LoginCLServlet.java admin.jsp ManageFilter.java xml配置 Filter 过滤器 url-pattern Filter 过滤器生命周期 ● Filter 生命周期图 FilterConfig ●…

RabbitMQ-后台使用

1、首先本地启动rabbitMQ,登录网址 http://localhost:15672/ 默认账号与密码都是gust 2、使用 user:创建用户 virtual-host:创建某个项目单独使用一个单独host和用户 3、命令添加用户与授权 添加用户 rabbitmqctl add_user admin admin 设置permissions rabbitmqctl set_…

Oracle系列之九:一文搞懂Oracle常用函数

Oracle常用系统函数 1. 字符串函数2. 数学函数3. 日期函数4. 聚合函数5. 其他 Oracle是一种关系型数据库管理系统&#xff0c;它提供了许多内置函数&#xff0c;以便用户可以更轻松地处理数据。 1. 字符串函数 &#xff08;1&#xff09;lengthb/length 计算字符串长度 len…

Linux常用命令整理

Linux常用命令整理 1. cat显示2. reboot 重启3. cd切换目录4. ls目录查看5. mkdir创建目录6. rm 删除文件7. mv目录修改8. cp拷贝9. find查找10. touch新建文件11. vi/vim修改文件12. chmod改变权限13. tar -zcvf 打包文件14. tar -xvf 解压文件15. grep文本搜索16. su, sudo17…

数据库学习总结(MySQL)

一.为什么要使用数据库? 在我们平时存储数据的时候,往往采用文件存储即可,所以,为什么要使用数据库呢? 原因在于,文件存储数据有以下缺点: 文件的安全性问题 文件不利于数据查询和管理 文件不利于存储海量数据 文件在程序中控制不方便 为了解决上述问题,我们创造了更适合…

Revit构件显隐:参数和插件控制构件显隐性操作

一、如何通过参数来控制族中不同构件的显隐性? 在这里&#xff0c;将它分享给大家~ 首先&#xff0c;我们在项目中任意绘制一道墙&#xff0c;然后任意布置一个带有门把手的门&#xff0c;如下图&#xff1a; 接着&#xff0c;我们【双击】进入这个门族的编辑界面&#xff0c;…

C++ 互斥锁原理以及实际使用介绍

兄弟姐妹们&#xff0c;我又回来了&#xff0c;今天带来实际开发中都需要使用的互斥锁的内容&#xff0c;主要聊一聊如何使用互斥锁以及都有哪几种方式实现互斥锁。实现互斥&#xff0c;可以有以下几种方式&#xff1a;互斥量&#xff08;Mutex&#xff09;、递归互斥量&#x…

掌握虚拟专用网络配置

目录 一、防火墙的IPSEC VPN 二、DSVPN 一、防火墙的IPSEC VPN 总体拓扑如下&#xff1a;实现PC间的加密通信。 FW1的配置&#xff1a;划分接口配置地址。 定义感兴趣流&#xff1a; 注&#xff1a;什么是感兴趣流&#xff1f;答&#xff1a;感兴趣流是VPN的术语&#xff0…

银行数字化转型导师坚鹏:数字化思维创新与金融业转型升级

数字化思维创新与金融业转型升级 课程背景&#xff1a; 很多金融机构存在以下问题&#xff1a; 金融机构的员工不知道需要具备什么样的数字化思维 不清楚数字化思维对金融机构转型升级的重要影响&#xff1f; 不清楚数字化背景下如何进行金融机构转型升级&#xff1f; …

Linux 块设备 EMMC 驱动介绍

目录: 高质量文章导航-持续更新中 前置:硬件接口 EMMC(Embedded Multi-Media Card)是一种用于存储和传输数据的嵌入式存储器(芯片),通常用于移动设备和嵌入式设备中。Linux内核提供了一个通用的EMMC驱动框架,可以支持各种不同的EMMC设备。 EMMC总线采用了典型的主从…

通过Python的PIL库给图片添加图片水印

文章目录 前言一、素材准备1.原图2.水印图 二、使用PIL库给图片添加图片水印1.引入库2.定义图片路径3.打开原图4.打开水印图片5.计算水印图片大小6.计算原图大小7.调整水印图片大小7.1调整前7.2调整后 8.计算水印图片位置8.1左上8.2左下8.3右上8.4右下8.5中间 9.添加水印10.保存…

Windows11台式机连接Type-C触摸屏显示器

我的设备是GoBiggerR便携触控屏&#xff0c;有1个mini-HDMI和2个USB-C接口。家用的是台式机&#xff0c;玩一些游戏用触控比较方便&#xff0c;于是想把触控屏利用上。 先说结论&#xff0c;我的方案是使用arpara VR DisplayPort 1.4数据线。 arpara 5K VR头显配件3.5米数据线…

U-Boot 初次编译

1.在 Ubuntu 中创建存放 uboot 的目录 &#xff0c;比如我的是/home/hsj/linux/IMX6ULL/uboot,然后在此目录 下新建一个名为“alientek_uboot”的文件夹用于存放 uboot 源码。alientek_uboot 文件夹创建成功以后使用 FileZilla 软件将正点原子提供的 uboot 源码拷贝到此目录中.…

Docker 部署 MySQL 一主多从

服务器规划&#xff1a;使用docker方式创建&#xff0c;主从服务器IP一致&#xff0c;端口号不一致 主服务器&#xff1a;容器名 mysql-master&#xff0c;端口 3306从服务器&#xff1a;容器名 mysql-slave1&#xff0c;端口 3307从服务器&#xff1a;容器名 mysql-slave2&am…

springboot+vue幼儿园管理系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的幼儿园管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌…

删除Android手机自带应用

目录 1、下载手机adb插件 2、进入开发者模式 3、删除应用 4、之后记得关闭手机usb及开发模式 1、下载手机adb插件 Downloads - ADB Shell 之后路径行输入cmd&#xff0c;或者winr&#xff0c;进入该目录&#xff1a; 2、进入开发者模式 设置--系统--关于手机--快速多次点…

YOLOv7+双目实现三维跟踪(python)

YOLOv7双目实现三维跟踪&#xff08;python&#xff09; 1. 目标跟踪2. 测距模块2.1 测距原理2.2 添加测距 3. 细节修改&#xff08;可忽略&#xff09;4. 实验效果 相关链接 1. YOLOV5 双目测距&#xff08;python&#xff09; 2. YOLOV7 双目测距&#xff08;python&#x…

快速发展、持续领跑,软件顶级盛会第二届中国国际软件发展大会成功召开

2023年4月18日&#xff0c;第二届中国国际软件发展大会在北京国家会议中心召开&#xff0c;工业和信息化部党组成员、副部长王江平出席大会并致辞。 王江平副部长表示&#xff0c;党的十八大以来&#xff0c;我国软件产业快速发展&#xff0c;核心技术持续突破&#xff0c;产业…

LiveCharts2 初步认识

文章目录 1 LiveCharts2 是什么&#xff1f;2 LiveCharts2 可以做什么&#xff1f;3 简单使用LiveCharts2 &#xff0c;实现动态曲线图 1 LiveCharts2 是什么&#xff1f; GitHub&#xff1a;https://github.com/beto-rodriguez/LiveCharts2 官网&#xff1a; https://lvchar…