记一次mysql多表查询(left jion)优化案例
一次mysql多表查询(left jion)优化案例
在新上线的供需模块中,发现某一个查询按钮点击后,出不来结果,找到该按钮对应sql手动执行,发现需要20-30秒才能出结果,所以服务端程序判断超时,故先不显示结果
以下是对这条查询的优化记录
1 数据库配置
数据库配置:4C8G
主表数据:3W+
2 sql语句
提取sql语句,简化如下
SELECT
taba.id,
taba.title,
taba.type,
taba.end_time,
tabb.username,
tabc.orgname
FROM
taba
LEFT JOIN tabd ON tabd.info_id = taba.id
LEFT JOIN tabe ON tabe.sdo_id = taba.id
LEFT JOIN tabb ON tabb.id = taba.creator
LEFT JOIN tabc ON tabc.id = taba.organization_id
WHERE
taba.`STATUS` = 'PUBLISH'
AND tabd.type = 'INDEX'
AND tabd.`VALUE` = '1'
AND taba.info_type = 'SUPPLY'
GROUP BY
taba.id
ORDER BY
taba.create_time DESC
LIMIT 100
3 优化记录
3.1 数据库索引
首先第一反应,查sql是否走了索引
EXPLAIN
select ......
从索引检查结果发现
tabe只有主键索引,没有sdo_id的索引
经过确定sdo_id是通过uuid制作,重复数很少,可以增加上索引- 其他条件虽然也没走索引,但是属于枚举值,重复性高,没有加索引的条件
经过添加索引,数据查询时间降低到3秒以内,所以正确的索引才是王道
3.2 返回数据限制
经过与开发人员沟通,确定可以每次只取10条数据,所以要求他们更改limit语句限制为limit 10
经过修改limit语句,数据库直插时间已经变味1.7秒
3.3 spring框架错误的conut *
经过前两部优化,按理2秒左右app就能显示数据,但是时间上却需要4秒钟
通过sql慢查询日志,发现在这条sql执行前,spring框架自动执行了一个select count(0) from (......)的操作来做分页,但是所以导致查询时间是理论上的2倍
再次与开发确定,不用框架的自动分页功能,改为代码层手动分页
结果修改框架的分页,app查询时间达到2秒内,已基本得到解决
3.4 极限优化limit
查询优化到2秒,已基本可以接受,但是先到数据才3万多行,感觉还是不能接受,继续找原因,发现如下:
- 3万+数据,但是sql执行结果却显示扫描了100多万行数据
观察sql语句,可以发现是先做了多次left join后,对结果取limit,那能不能先取limit 10再进行查询呢,于是把sql优化如下
SELECT
taba.id,
taba.title,
taba.type,
taba.end_time,
tabb.username,
tabc.orgname
FROM
taba
LEFT JOIN tabd ON tabd.info_id = taba.id
LEFT JOIN tabe ON tabe.sdo_id = taba.id
LEFT JOIN tabb ON tabb.id = taba.creator
LEFT JOIN tabc ON tabc.id = taba.organization_id
WHERE
tabd.type = 'INDEX'
AND tabd.`VALUE` = '1'
AND taba.id IN (
SELECT * FROM
( SELECT id FROM taba WHERE `STATUS` = 'PUBLISH'
AND info_type = 'SUPPLY'
ORDER BY taba.create_time DESC LIMIT 10 ) AS tmp
)
优化方法:
- 将limit语句通过子查询放入where条件中
- sql将先执行子查询获取10条
id数据 - 让后将10条
id拿去前面做join
优化结果
- sql执行时间达到0.117秒,再一次质的飞跃
- 基本做到秒加载,点击按钮,一秒内出结果
3.4.1
第二天一觉醒来,觉得这个sql还有值得优化的地方,于是分别提取出各语句执行后,发现耗时最长的是limit条件,耗时0.09s
优化方法
- 查找发现原因是
order by条件create_time列未加索引,导致做了一次全表扫描 - 于是增加上
create_time索引
优化结果
- sql执行时间变为0.068s
- 再次说明正确的索引才是王道
3.5 优化后记
其实sql中还有几个可以优化的地方,比如:
- 4个
left join中的3个可以改成inner join - 原语句的
group by,经测试改掉可优化0.3秒(1.7秒处) - limit语句可以放到from处先处理等
但是:
- sql优化是长期的过程
- 优先解决影响业务的慢查询
- 优先解决占时间比例大的慢查询
- 咱是运维,不是DBA,还有高可用等着我玩
- 因此已经达到要求,甚至超额完成,就不用再管芝麻了
记一次mysql多表查询(left jion)优化案例的更多相关文章
- MySQL 回表查询 & 索引覆盖优化
回表查询 先通过普通索引的值定位聚簇索引值,再通过聚簇索引的值定位行记录数据 建表示例 mysql> create table user( -> id int(10) auto_incre ...
- MySQL多表查询之外键、表连接、子查询、索引
MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...
- Mysql 单表查询 子查询 关联查询
数据准备: ## 学院表create table department( d_id int primary key auto_increment, d_name varchar(20) not nul ...
- (转)Mysql 多表查询详解
MySQL 多表查询详解 一.前言 二.示例 三.注意事项 一.前言 上篇讲到mysql中关键字执行的顺序,只涉及了一张表:实际应用大部分情况下,查询语句都会涉及到多张表格 : 1.1 多表连接有 ...
- MySQL多表查询回顾
----------------------siwuxie095 MySQL 多表查询回顾 以客户和联系人为例(一对多) 1.内连接 /*内连接写法一*/ select * from t_custom ...
- python 3 mysql 单表查询
python 3 mysql 单表查询 1.准备表 company.employee 员工id id int 姓名 emp_name varchar 性别 sex enum 年龄 age int 入职 ...
- python3 mysql 多表查询
python3 mysql 多表查询 一.准备表 创建二张表: company.employee company.department #建表 create table department( id ...
- Mysql 单表查询-排序-分页-group by初识
Mysql 单表查询-排序-分页-group by初识 对于select 来说, 分组聚合(((group by; aggregation), 排序 (order by** ), 分页查询 (limi ...
- Mysql 单表查询where初识
Mysql 单表查询where初识 准备数据 -- 创建测试库 -- drop database if exists student_db; create database student_db ch ...
随机推荐
- 波兰政府在继韩国之后也增加了对 Linux 的使用
导读 前段时间, 韩国政府起草了一项战略,准备采用基于 Linux 的开源操作系统全面取代 Windows 7,以摆脱对其的依赖. 目前,波兰的社会保险公司 ZUS( Zakład Ubezpiecz ...
- 基于linux下的NIST数字测试包安装过程
基于linux下的NIST数字测试包安装过程 1. 首先解决windows文件不能粘贴到Ubuntu的问题 选择利用VMware Tools进行解决 打开虚拟机VMware Workstation,启 ...
- javascript 自动选中容器里的文字
前些时间有这么个需求,需要实现选中div里面的文字,选中了的文字可直接按ctrl+v(或者右键)实现黏贴操作. html代码: <div id="text" class=&q ...
- Requests发Post请求data里面嵌套字典
一.Post请求,data里面嵌套字典 Requests发Post请求,data里面嵌套字典的常见形式如下: info = { "appid": "123", ...
- 面试话痨(二)C:JAVA String,别以为你穿个马甲我就不认识你了
面试话痨系列是从技术广度的角度去回答面试官提的问题,适合萌新观看! 面试官,别再问我火箭怎么造了,我知道螺丝的四种拧法,你想听吗? String相关的题目,是面试中经常考察的点,当面试中遇到了St ...
- 1. postman使用
postman使用教程: https://blog.csdn.net/fxbin123/article/details/80428216 http://bayescafe.com/tools/use- ...
- .NET的资源并不限于.resx文件
为了构建一个轻量级的资源管理框架以满足简单的本地化(Localization)的需求,我试图直接对现有的Resource编程模型进行扩展.虽然最终没能满足我们的需求,但是这两天也算对.NET如何进行资 ...
- Windows软件包管理工具 - Chocolatey
概述 windows下的软件安装管理器(用于自动管理软件安装,更新,卸载) Chocolatey引入了真正的包管理概念,使您能够对事物进行版本控制,管理依赖关系和安装顺序,更好的库存管理以及其他功能 ...
- 基于 websocket 的多端桥接平台
我们现在的业务是基于新闻客户端实现的,都要经过新闻客户端的环境,进行前后端数据上的交互.但是我们在调试过程中,非常的不方便. 通常使用的工具有:modheader, postman, fiddler ...
- 直方图均衡算法(Histogram Equalized)
Lab1: Histogram Equalization 1. 实验环境(C++) 操作系统版本 MacOS Catalina 10.15 OpenCV4.0 (imgcodecs | core | ...