業務上須要作一個查詢,由於是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