子查询在WHERE中不一定慢MySQL 8.0/PostgreSQL对简单IN子查询有半连接优化若含GROUP BY、ORDER BY或相关子查询则退化为嵌套循环此时应改写为JOIN。子查询在 WHERE 里跑得慢是不是该换 JOIN不一定。MySQL 8.0 和 PostgreSQL 对 WHERE ... IN (SELECT ...) 类子查询做了半连接优化但前提是子查询不带 GROUP BY、ORDER BY 或相关子查询比如引用外层表字段。一旦出现这些优化器大概率放弃转换直接走嵌套循环——这时候性能就崩了。实操建议用 EXPLAIN 看执行计划如果出现 DEPENDENT SUBQUERY 或多层 select_typeSUBQUERY说明没被优化优先考虑改写为 JOIN若子查询只查单列且结果集小IN 可能比 JOIN 更快——因为避免了临时表和去重开销PostgreSQL 中IN (VALUES ...) 比子查询快得多MySQL 则建议用 IN (1,2,3) 预先展开别依赖运行时子查询LEFT JOIN WHERE IS NULL vs NOT EXISTS哪个不漏数据语义等价但行为有坑。很多人用 LEFT JOIN ... WHERE right_table.id IS NULL 找“不存在匹配”的记录结果发现 right_table 的字段本身允许 NULL导致 IS NULL 判定失效——这不是语法错是逻辑误判。实操建议NOT EXISTS 更安全它只关心子查询是否返回行不依赖字段值天然规避 NULL 干扰LEFT JOIN 方式必须确保 ON 条件里用的是非空键如主键或 NOT NULL 的外键且 WHERE 判定的字段来自右表且定义明确SQL Server 对 NOT EXISTS 生成更优计划MySQL 5.7 前者可能比后者多一次索引扫描但 8.0 差异已很小子查询当派生表FROM 子句和 JOIN 混用时索引还生效吗大概率失效。把子查询塞进 FROM 写成 (SELECT ... FROM t1 WHERE cond) AS dt再跟其他表 JOINMySQL 会先物化这个子查询结果生成临时表默认无索引。哪怕原表 t1 上有完美索引物化后也丢了。 通义听悟 阿里云通义听悟是聚焦音视频内容的工作学习AI助手依托大模型帮助用户记录、整理和分析音视频内容体验用大模型做音视频笔记、整理会议记录。