记录一次慢SQL优化:大表关联小表->拆解为单表查询

本文讲述了针对一个慢查询SQL的优化过程。通过分析发现,由于小表全表扫描导致效率低下。优化策略包括:先单独查询小表获取关键信息,减少无效联查;利用Java代码拼接结果;并考虑对低频更新的小表进行缓存,以减轻数据库压力。经过优化,查询时间从15-20s降低到0.3-0.6s。
摘要由CSDN通过智能技术生成

前言:

最近一段时间总是会收到数据库CPU报警
在这里插入图片描述
一查发现有一个特别慢的SQL,调用的频率很高,并且查一次SQL15s以上,十分影响性能

SQL分析

这个sql是一个分页查询的sql,每次查出10条主表是cfg_category_organization (大约50W+数据)
需要补充部分信息:cfg_category (大约1000条数据)、cfg_org (大约2W数据)

按说这个数据量不大,但是就是非常慢

select
	b.*,
	co.organization_path,
	co.organization_full_name,
	a.name,
	a.status
from
	cfg_category_organization b
inner join cfg_category a on b.category_id = a.id
inner join cfg_org co on b.organization_code = co.organization_code
where
	b.is_delete = 0
	and co.is_delete = 0
	and a.is_delete = 0
	and co.organization_path like concat('/001/002/003/004', "%")
	and b.category_id = 7
order by
	b.status desc,
	b.update_time desc
limit 10;

用explain看一下,发现表cfg_category 、cfg_org 的rows是很少的,只有cfg_category_organization 几乎进行了全表扫描,开销较大。
在这里插入图片描述

SQL优化

因此我们可以采用,把小表查询出来的结果作为条件,in到大表中,并且对应的大表字段都是有索引的
1.cfg_category 表单独拎出来作为一个SQL,当有这张表的字段作为查询条件时,就select出这张表的key:

select id from cfg_category where is_delete = 0 and id = 7

如果说返回参数为0,后面的内容均不需要查了,肯定联查不出来任何数据,这样就减少了一小部分无效查询

2.同理cfg_org 表也单独拎出来,如果有这张表的字段作为查询条件的时候,就select出这张表的key:

select organization_code   from cfg_org where is_delete = 0 and organization_path like concat('/001/002/003/004', "%")

同理,如果说返回参数为0,后面的内容均不需要查了,肯定联查不出来任何数据,这样就减少了一小部分无效查询

3.如果前两步都能查出对应的数据,则对最大的表进行查询:

select
	b.*
from
	cfg_category_organization b
where
	b.is_delete = 0
	and b.organization_code in('004', '005')
	and b.category_id in (7)
order by
	b.status desc,
	b.update_time desc
limit 10

如果说没有任何查询条件,则SQL就是如下情况:

select
	b.*
from
	cfg_category_organization b
where
	b.is_delete = 0
order by
	b.status desc,
	b.update_time desc
limit 10

分页查询,充其量单表查询返回的结果就是10条,那么查出的10条,再组装一下,category_id 、organization_code 字段,分别去小表查一次,再利用Java代码拼接出来即可

select name,status from cfg_category where id in (7);
select organization_path,organization_full_name from cfg_org where organization_code in ('004','005');

优化后效果不错:平均15-20s查询的慢SQL,优化到0.3-0.6s
在这里插入图片描述

总结与改进

在上面优化,将一次慢SQL查询修改为5次单表查询+Java代码的辅助拼接,实际上还可以再次优化,如果说cfg_category 、cfg_org是有字段作为查询条件的,那么在前面查的那次就可以将对应的信息查出来,然后利用java代码获取key值(category_id、organization_code)
并且,根据业务场景来说,这两张小表的更新频率是比较低的,可以按照查询条件来做缓存,较少数据库的压力,进一步优化。

以上就是本次优化的心得,欢迎大家与我交流~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值