MySQL 8.0+不支持子查询并行,无论hint或optimizer_switch设置均无效;所谓“并行扫描”仅限InnoDB无索引全表扫描且需EXPLAIN FORMAT=TREE验证,子查询、聚合、LIMIT等场景均不触发。

MySQL 8.0+ 中嵌套查询默认不并行,连 hint 都无效
MySQL 目前(截至 2026 年)**不支持对子查询启用并行执行**,无论你加 /*+ PARALLEL(4) */ 还是设置 SET SESSION optimizer_switch='parallel_query=on',这些在 MySQL 中根本不存在——它压根没实现并行查询能力。你看到的「并行扫描」只可能出现在底层存储引擎的个别读取路径(如 InnoDB 的预读),但不是 SQL 层面的并行计划。
常见误判场景:
- 用
EXPLAIN FORMAT=TREE看到-> Index range scan多次出现,误以为是并行;其实是优化器为不同条件生成的多个索引扫描分支,仍串行执行 - 监控工具显示 CPU 多核占用高,归因于 SQL 并行;实际是多个连接并发跑相同嵌套查询,或大排序/临时表触发了线程池内多线程协作(非查询计划并行)
SQL Server 嵌套查询能否并行?取决于是否被展开
SQL Server 能对嵌套查询生成并行计划,但前提是:子查询必须被优化器「展平」(flattened)成 JOIN 或 APPLY,否则会作为独立的串行子树执行。典型卡点:
-
IN (SELECT ...)或EXISTS (SELECT ...)在含TOP、OFFSET/FETCH、聚合或窗口函数时,常被保留为未展开的 Nested Loops 子树,强制串行 - 子查询里用了
ORDER BY+LIMIT(如SELECT id FROM t2 ORDER BY ts DESC LIMIT 1),SQL Server 不会展开,直接走串行 TopN 算子 - 外层查询加了
OPTION (MAXDOP 1),整个计划包括所有子树都会禁用并行
验证方法:用 SET STATISTICS XML ON 查看执行计划,搜索 —— 若子查询对应节点的 Parallel 属性为 0,说明它没参与并行。
PostgreSQL 的嵌套查询并行限制更具体
PostgreSQL 10+ 支持并行查询,但对子查询有明确排除规则。以下情况子查询一定无法并行:
- 子查询出现在
WHERE中且含相关引用(correlated subquery),例如WHERE x IN (SELECT y FROM t2 WHERE t2.id = t1.ref) - 子查询使用了
UNION、INTERSECT、EXCEPT,即使无相关性,也不参与并行 - 子查询返回类型为
record或含复杂表达式(如jsonb_path_query),优化器跳过并行化尝试 -
work_mem设置过低,导致并行 worker 启动失败,回退为单线程
可手动干预的点:/*+ PARALLEL(t2 4) */ 提示仅对 FROM 中的基表生效,对子查询无效;若想并行,得先改写为 LATERAL JOIN 或 CTE 并确保 CTE 被物化(MATERIALIZED),再在外层 JOIN 上加并行提示。
为什么「检查查询提示」容易白忙活
多数人查并行问题第一反应是加 hint,但现实是:
- MySQL 没有并行 hint,所有
/*+ PARALLEL */类注释会被忽略,不报错也不生效 - Oracle 的
/*+ PARALLEL(subq 4) */只能作用于派生表(FROM (SELECT ...) subq),对WHERE EXISTS (SELECT ...)里的子查询无效 - SQL Server 的
OPTION (USE HINT('ENABLE_PARALLEL_PLAN_PREFERENCE'))是全局开关,不能指定某层子查询并行,且对未展开子查询无影响 - 真正起效的永远是「让子查询消失」:用 JOIN 替代 EXISTS、用 CTE + MATERIALIZED 强制物化中间结果、把多层嵌套压平为单层带条件的聚合
最常被忽略的一点:并行收益只在数据量 > 数百万行且 CPU 不饱和时才明显;小表嵌套查询强行并行反而增加调度开销,响应更慢。










