IN是把外表和内标作Hash连接,而Exists是对外表作Loop循环,每次Loop循环在对内表进行查询
认为EXISTS比IN效率高的说法是不准确的

  1. 如果查询的两个表大小相当,那么IN和EXISTS差别不大
  2. 如果两个表中一个较小,一个较大,则子查询表大的用EXISTS,子查询表小的用IN

示例一 表A(小表) 表B(大表)

  1. // 效率低,用到了A表上cc列的索引
  2. SELECT * FROM A WHERE cc IN (SELECT cc from B)
  3. // 效率高,用到了B表上的cc列的索引
  4. SELECT * FROM A WHERE EXISTS (SELECT cc from B WHERE cc = A.cc)

示例二 表A(大表) 表B(小表)

  1. // 效率高,用到了A表上cc列的索引
  2. SELECT * FROM B WHERE cc IN (SELECT cc from A)
  3. // 效率低,用到了A表上的cc列的索引
  4. 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 快