通过减少回表和增加冗余字段,优化SQL查询效率
通过减少回表和增加冗余字段,优化SQL查询效率
- 一、减少回表
- 1:分析执行计划
- 2:子查询SQL
- 3:分析思路
- 4:业务insert_monoth聚合
- 5:优化效果
- 二、增加冗余字段
- 1:分析执行计划
- 2:表索引index_test1_test2_test3已经存在
- 3:分析思路
- 4:优化效果
一、减少回表
原始SQL
select temp.basicId,
temp.type,
temp.insert_monoth
from(select t2.basicId,
t2.type,
t2.insert_monothfrom t2where edition_id in (...)
) temp
left join test3 t3 on temp.item_id = t3.item_id
group by temp.basicId, t3.type,t3.insert_monoth
1:分析执行计划
发现原始SQL使用子查询引起的临时表,而且子查询很慢
type为 ALL、ref、range;Extra为Using temporary、Using where、Using index condition
2:子查询SQL
虽然走了索引但是发现执行计划"Using index condition",代表使用了索引下推来减少回表,于是需要减少回表,才能提升查询效率
3:分析思路
由于子查询查询字段过多,无法使用覆盖索引,此时就需要回表查询数据。于是修改SQL只获取id字段,得到临时表,然后用id字段inner join临时表,进而查询出需要的字段
优化后SQL
select distinct t1.basicId
from test1 t1
inner join (select id from test1 where edition_id in (...)group by basicId) temp1 on temp1.id = t1.id
4:业务insert_monoth聚合
对应内存中的临时表进行group by导致无法走索引,而且group by字段越多,效率越差。尤其insert_monoth会造成10倍消耗,所以在SQL中删除此过滤条件。在业务代码按照insert_monoth进行二次聚合。
5:优化效果
最终查询时间欧诺个2.4s优化到0.7s!
二、增加冗余字段
原始SQL
select test1,test2,test3,date_format(insert_date,'%Y-%m') as insertMonth
from t where (test1,test2,test3) in (...)
and date_format(insert_date,'%Y-%m') = '2025-08'
group by test1,test2,test3
1:分析执行计划
type列为range,Extra列为Using where
2:表索引index_test1_test2_test3已经存在
3:分析思路
where条件虽然命中索引,但是insert_date未命中,而且where查询条件做函数运算,严重影响查询效率。
可以将t表新增1个冗余字段insert_month,直接将date_format(insert_date,‘%Y-%m’)结果保存到t表中,然后索引修改为index_test1_test2_test3_insert_month
4:优化效果
500个入参,生产环境查询时间由3s降低到了0.66s