2024年4月21日发(作者:)

EXISTS、IN与JOIN性能分析

EXISTS、IN与JOIN,都可以用来实现形如“查询A表中在(或不在)B表中的记录”

的查询逻辑。

在论坛上看到很多人对此有所误解(如关于in的疑惑、用 外连接 和 Is Null 代替

not in两帖),特做一简单测试。

测试结果:

测试代码较长,附于本帖最后。

图表中百分数表示同一组3个查询的执行时间比例。红色表示3个语句中最慢,绿色

表示3个语句中最快的,并列则没加颜色。

其中索引只测试了聚集索引,当表中字段较多且查询字段是非聚集索引时,选择执行

计划的条件比较复杂,没有测试。并且当表中数量变化后,执行计划可能也有差异。图表

反映了3种查询方式的解析机制的不同,基本结论是类似的,但具体情况还要视执行计划

而定。

分析结论:

通常情况下,3种查询方式的执行时间:

EXISTS <= IN <= JOIN

NOT EXISTS <= NOT IN <= LEFT JOIN

只有当表中字段允许NULL时,NOT IN的方式最慢:

NOT EXISTS <= LEFT JOIN <= NOT IN

综上:

IN的好处是逻辑直观简单(通常是独立子查询);缺点是只能判断单字段,并且当NOT

IN时效率较低,而且NULL会导致不想要的结果。

EXISTS的好处是效率高,可以判断单字段和组合字段,并不受NULL的影响;缺点是

逻辑稍微复杂(通常是相关子查询)。

JOIN用在这种场合,往往是吃力不讨好。JOIN的用途是联接两个表,而不是判断一

个表的记录是否在另一个表。

编程建议:

(以下三条建议中EXISTS和IN同时代指肯定式逻辑和加NOT后的否定式逻辑)