IN是把外表和内标作Hash连接,而Exists是对外表作Loop循环,每次Loop循环在对内表进行查询
认为EXISTS比IN效率高的说法是不准确的
- 如果查询的两个表大小相当,那么IN和EXISTS差别不大
- 如果两个表中一个较小,一个较大,则子查询表大的用EXISTS,子查询表小的用IN
示例一 表A(小表) 表B(大表)
// 效率低,用到了A表上cc列的索引SELECT * FROM A WHERE cc IN (SELECT cc from B)// 效率高,用到了B表上的cc列的索引SELECT * FROM A WHERE EXISTS (SELECT cc from B WHERE cc = A.cc)
示例二 表A(大表) 表B(小表)
// 效率高,用到了A表上cc列的索引SELECT * FROM B WHERE cc IN (SELECT cc from A)// 效率低,用到了A表上的cc列的索引SELECT * FROM B WHERE EXISTS (SELECT cc from A WHERE cc = B.cc)
NOT IN 和 NOT EXISTS
如果查询语句使用了NOT IN,那么内外表都进行全表扫描,没有用到索引
而NOT EXISTS的子查询依然能够用到表上的索引
所以无论哪个表大,用NOT EXISTS都比NOT IN 快
