必须设为on才算真正启用:mysql 8.0.30+并行查询默认关闭,仅当parallel_query=on且配合parallel_threads_limit与innodb_parallel_read_threads配对设置,并通过explain format=tree验证输出“-> parallel scan on table_name”时,才实际生效。

parallel_query 必须设为 ON 才算真正启用并行查询
MySQL 8.0.30+ 的并行查询是实验性功能,默认 parallel_query 为 OFF,不设成 ON 就等于没开——哪怕其他参数全对,查询也只会串行执行。
这个变量是全局开关,影响所有新连接:
-
SET GLOBAL parallel_query = ON—— 生效于后续新建连接,已存在的会话不受影响 - 写入
my.cnf的[mysqld]段更稳妥:parallel_query = ON - 不能只靠
innodb_parallel_read_threads > 0来“间接开启”:该参数单独设为 4 或 8,完全无效,它只在parallel_query = ON前提下才参与调度
parallel_threads_limit 和 innodb_parallel_read_threads 要配对设置
这两个参数不是独立生效的,必须满足数值约束关系,否则并行路径直接被优化器跳过:
-
parallel_threads_limit控制单条 SQL 最多用几个线程(含主线程),建议值为2–4;设太高(如 16)反而因调度开销拖慢 -
innodb_parallel_read_threads必须 ≥parallel_threads_limit - 1,因为主线程占 1 个,其余由 InnoDB 层分配 - 典型安全组合:
SET GLOBAL parallel_threads_limit = 3+SET GLOBAL innodb_parallel_read_threads = 2 - 注意:
innodb_parallel_read_threads是会话级变量,SET SESSION可覆盖全局值,但SET GLOBAL不影响已有连接
EXPLAIN FORMAT=TREE 是唯一可信的触发证据
普通 EXPLAIN 或 EXPLAIN FORMAT=JSON 完全不显示并行信息,别被 "parallel_table_scan": true 这类字段误导——它只是优化器“考虑过”并行,不代表实际执行时启用。
真正有效的验证方式只有一种:
- 执行
EXPLAIN FORMAT=TREE SELECT ... - 输出第一行必须是
-> Parallel scan on table_name - 如果看到的是
-> Table scan on table_name或-> Index range scan on table_name,说明并行根本没走,参数或语句条件不满足 - 常见失效原因:WHERE 条件命中了索引、语句带
LIMIT/GROUP BY/ORDER BY、表太小(REPEATABLE READ 且存在 gap lock
并行只发生在存储引擎层,执行器不参与分片
并行扫描是 InnoDB 内部发起的物理页读取行为,执行器(server layer)只做结果归并,这意味着:
- JOIN、ORDER BY、DISTINCT、聚合函数的最终计算仍在主线程完成,不会拆到 worker 线程
-
COUNT(*)可以下推到每个 worker 计数,但COUNT(id)或SUM(salary)在部分版本中不保证下推 - 即使并行扫描成功,如果后续阶段(如排序、去重)成为瓶颈,整体耗时改善有限
- 真正能受益的场景非常窄:无索引、无过滤、无 LIMIT、无聚合、大表全扫(> 百万行)——其他情况调参基本白忙
并行查询的“开启”动作本身很简单,但它的生效极度依赖语句结构、表状态和运行时上下文。最容易被忽略的是:即使 EXPLAIN FORMAT=TREE 显示 Parallel scan,只要事务中有未提交写、buffer pool mutex 竞争高、或 SSD 队列深度被压满,InnoDB 仍可能在执行时静默降级为单线程。











