业务上须要作一个查询,由于是Web及时响应,因此对响应时间有要求,原业务场景是须要从无库存订单中剔除绑定闲置库存,因单条sql查询实现复杂,故考虑用差集方式:html
select a.col1, a.col2 from a where a.id = ? and not exists ( select b.id from b left join c on b.id = c.id where b.id = ? and b.id = a.id) order by a.id
数据量: a,b,c皆在百万数据量级,排除其余非必要过滤字段,id皆有btree索引mysql
运行:2s左右sql
环境:阿里云(最基本线上服务性能,数据库运行状态保持在10个以上连接)数据库
原sql其实用的是not in,参考了文章1,在同等数据量时not in 会走屡次全表查询(由于!=无对应索引),而not exists会走子查询索引,因此not exists更快。故先用not exists替换了not in(语法有差别,替换时须要作b.id = a.id的关联)。在参考文章2之后,尝试用left join进行优化(其中关于mysql子查询优化器说法待考量,后分析文章3),改为以下方式:性能
select a.col1, a.col2 from a left join ( select b.id from b left join c on b.id = c.id where b.id = ? ) as r on a.id = r.id where b.id = ? and r.id is null order by a.id
思路即是先将子查询符合的行经过left join查询到,而后经过is null条件获得剩下的部分(即知足需求的记录)。最终运行时间在0.7s。优化
ref:阿里云
1. https://www.cnblogs.com/beijingstruggle/p/5885137.html.net
2. https://blog.csdn.net/zyz511919766/article/details/49335647htm
3. https://www.cnblogs.com/wxw16/p/6105624.html?utm_source=itdadao&utm_medium=referralblog