首页/数据/SQL 速查/子查询与 JOIN 的选择
本包目录(311 条)

子查询与 JOIN 的选择

同一需求可以写成 IN/EXISTS 或 JOIN:核心差异在“是否放大行数”与“是否输出另一表列”,性能以执行计划实测为准。

SQL 速查数据更新于 2026-10-12

语义对比

语义对比
-- 只筛用户:不放大行数
SELECT * FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

-- 输出订单列:一对多会放大行数
SELECT u.*, o.id AS order_id
FROM users u
JOIN orders o ON o.user_id = u.id;
半连接IN / EXISTS:不放大行数
普通连接JOIN:输出两侧列,按匹配行数展开
选择需要输出副表列用 JOIN;只做筛选用 EXISTS/IN

易错点

  • 用 JOIN 代替 IN 又忘记 DISTINCT,会因行放大得到重复结果
  • “子查询一定更慢”是过时结论:优化器会把 IN 改写为半连接,以 EXPLAIN 为准

数据来源与参考

  • MySQL 8.0 Reference Manual · Optimizing Subqueries
  • PostgreSQL Documentation · Subquery Expressions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌