Skip to content

SQL 中 EXISTS 和 IN 语句的区别

由于查询时执行流程不同,因此在不同情况下查询效率各有优劣。

IN

确定给定的值是否与子查询或列表中的值相匹配。

IN 在查询的时候:

  • 首先查询子查询的表,
  • 然后将内表和外表做一个笛卡尔积,
  • 然后按照条件进行筛选。

相对内表比较小的时候,IN 的速度较快。

EXISTS

指定一个子查询,检测行的存在。

EXISTS 在查询时:

  • 首先,我们先查询的不是子查询的内容,而是查我们的主查询的表,
  • 然后,根据表的每一条记录,执行 EXISTS 语句,依次去语句中的查询条件是否成立。
  • 如果成立则返回 true 不成立则返回 false。如果返回的是 true 的话,则该行结果保留,如果返回的是 false 的话,则删除该行,最后将得到的结果返回。

区别和应用场景

IN 和 EXISTS 的区别:

  • 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用 in
  • 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用 exists

其实我们区分 IN 和 EXISTS 主要是造成了驱动顺序的改变(这是性能变化的关键),如果是 EXISTS,那么以外层表为驱动表,先被访问,如果是 IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外 IN 时不对 NULL 进行处理。

IN 是把外表和内表作 HASH 连接,而 EXISTS 是对外表作 LOOP 循环,每次 LOOP 循环再对内表进行查询。一直以来认为 EXISTS 比 IN 效率高的说法是不准确的。

NOT IN 和 NOT EXISTS

  • 如果查询语句使用了 NOT IN,那么内外表都进行全表扫描,没有用到索引;
  • NOT EXISTS 的子查询依然能用到表上的索引。

所以无论那个表大,用 NOT EXISTS 都比 NOT IN 要快

Released under the MIT License.