子查询和索引一直是性能优化的常客
查询简单的时候还好办,拿掉子查询,先join再group by聚合
碰到复杂的查询,里外查询维度不统一,还牵扯到别的计算指标,有点难搞
用临时表是可行的,写过程,创建临时表,加索引,删掉临时表。
这里提供另一种思路:
如果where子句的过滤条件和子查询有关,多写一遍过滤条件就可以避免全表扫描了。
项目中实际遇到的情况
背景:优化某个sql的查询性能
版本:mysql 5.7
通过查询计划可以看到之前的查询好几张表都是全扫了一遍,小表还无所谓,最后一行的eo却是一张大表,更灾难的是,相同的逻辑还要 union all 一次,因为有 eo 历史表
eo数据量150万,eo历史表数据量560万
原先的eo子查询这么写的
用shift id关联,恰好where子句中要过滤 shift date,这里hard code 过滤条件只是测试使用,生产环境为变量
于是eo子查询可以再关联一次shift,并加上过滤条件
再次查看执行计划,发现eo用上了索引
查询提速明显
之前查询耗时
优化 eo子查询后
写在最后,以上子查询去重性能优化的方法适用范围有限,仅提供一种思路供参考。