LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

SQL查询中 IN 和 EXISTS 的区别与使用场景?

admin
2025年12月10日 21:26 本文热度 14

IN 和 EXISTS 的区别与使用场景?

在写多表查询时,我们经常会看到这样的两种写法:

-- 用 IN
SELECT
 * 
FROM
 user 
WHERE
 id IN (SELECT user_id FROM orders);

-- 用 EXISTS

SELECT
 * 
FROM
 user u
WHERE
 EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

两者都能实现“筛选存在关系”,那到底有什么区别?
是不是 EXISTS 性能更好?
IN 一定比较慢吗?


一、IN 和 EXISTS 的本质区别

要理解区别,必须记住一句话:

IN 是把子查询结果返回给外层,外层再匹配;
EXISTS 是拿外层每一行去子查询中试探。

换句话说:

方式
工作原理
IN
将子查询结果全部取出 → 临时表 → 外层匹配
EXISTS
外层循环每一行 → 子查询判断是否存在(true/false)

理解这个差异,对后面的性能分析非常重要。


二、IN 适合“子查询结果小”的场景

例如:

SELECT * 
FROM
 order
WHERE
 product_id IN (SELECT id FROM product WHERE type='book');

如果 product 表只有 200 条书籍,IN 的效率非常高:

  • • 子查询先执行 → 得到约 200 个 ID
  • • 主查询用二分查找快速匹配

✔ 子查询结果小 → IN 运行很快
✔ 子查询结果可使用索引 → 如 product.id 是主键


三、EXISTS 适合“主查询数据量大”的场景

EXISTS 的逻辑是这样的:

SELECT *
FROM
 user u 
WHERE
 EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

执行过程:

  1. 1. user 表每拿一条记录 u
  2. 2. 去 orders 表中找是否有匹配记录
  3. 3. 找到第一条就停止(非常快)
  4. 4. 返回 true/false

所以:

✔ EXISTS 更适合外层表很大,而子查询表比较大或有索引
✔ 相关子查询(关联外层字段)更适合用 EXISTS


四、NOT IN vs NOT EXISTS(性能与结果都不同)

这一段是面试高频点。

NOT IN 性能差且可能导致逻辑错误

如果子查询中有 NULL:

SELECT id FROM user WHERE id NOT IN (1, 2, NULL);

结果是 —— 永远返回空!

因为 NULL 与任何比较结果都是 UNKNOWN。

并且:

  • • NOT IN 不能使用索引
  • • NOT IN 必须扫描全部结果

NOT EXISTS 才是正确写法

SELECT * 
FROM
 user u 
WHERE
 NOT EXISTS (
    SELECT
 1 FROM orders o WHERE o.user_id = u.id
);

✔ NULL 不会影响结果
✔ 可以用索引
✔ 性能更高


五、IN vs EXISTS 的性能比较(通俗总结)

比较项目
IN
EXISTS
子查询结果
大时慢,小时快
不受结果大小影响
外层表大小
小时差不多
外层表大时更快
是否能用外层索引
是否能使用子查询索引
是否依赖临时表
有可能
不会
是否受 NULL 影响
是否支持相关子查询优化
较弱
更强

一句话总结:

子查询小 → 用 IN
外层表大 → 用 EXISTS
NOT IN → 永远用 NOT EXISTS 替代


六、实战总结(最常用的三条)

1)IN 更适合 “值列表” 或 “小表”

SELECT * FROM user
WHERE
 country IN ('CN', 'US', 'JP');

2)EXISTS 更适合 “大表关联”

SELECT * FROM user u
WHERE
 EXISTS (
    SELECT
 1 FROM orders o
    WHERE
 o.user_id = u.id
);

3)避免 NOT IN,永远用 NOT EXISTS


七、总结

IN 是拿子查询结果去匹配外层;
EXISTS 是拿外层每一行去子查询试探。

如果子查询的数据量大,IN 会很慢;
如果外层表很大,EXISTS 更高效。

NOT IN 会受到 NULL 影响且索引利用差;
所以实际开发中推荐使用 NOT EXISTS。

简单讲:
IN 适合小表,EXISTS 适合大表;
NOT IN 用 NOT EXISTS 替代。


阅读原文:原文链接


该文章在 2025/12/11 9:50:47 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved