唯一可信的并行触发证据是explain format=tree输出首行为“-> parallel scan on table_name”;其他方式如format=json中的"parallel_table_scan":true仅表示优化器考虑过并行,不保证实际启用。

EXPLAIN FORMAT=TREE 是唯一可信的并行触发证据
普通 EXPLAIN 或 EXPLAIN FORMAT=JSON 完全不显示并行是否实际启用,别被 "parallel_table_scan": true 这类字段误导——它只是优化器“考虑过”并行,不代表执行时真用了。唯一能确认并行已生效的方式是:EXPLAIN FORMAT=TREE SELECT ...,然后检查输出第一行是否为 -> Parallel scan on table_name。
常见误判场景包括:
- 语句带
LIMIT、ORDER BY、GROUP BY、子查询或窗口函数,优化器直接跳过并行路径 - WHERE 条件命中了任意索引(哪怕只用到前缀),退化为
-> Index range scan on table_name - 表太小(例如
rows ),优化器静默降级为串行 - 表是分区表、临时表、MyISAM 或 Memory 引擎,并行完全无效
用 EXPLAIN ANALYZE 查看真实并行工作负载
EXPLAIN ANALYZE 能暴露运行时行为,比静态计划更可靠。重点搜索输出中是否含 "parallel_workers": N 和 "rows_examined_per_worker" 字段:
- 若
N > 1且各 worker 的rows_examined_per_worker接近总扫描量 / N,则说明数据分片和并行读取已触发 - 若
parallel_workers为 1,或字段缺失,说明并行根本没参与执行 - 注意:该命令会真实执行 SQL,生产环境慎用;建议先在低峰期或只读从库上验证
查 performance_schema 线程快照确认多线程活跃
并行扫描会在 InnoDB 层启动多个后台读取线程,主线程只负责结果归并。运行查询的同时执行:
SELECT THREAD_ID, PROCESSLIST_INFO FROM performance_schema.threads WHERE PROCESSLIST_INFO LIKE '%SELECT%';
观察是否出现多个 query exec 类型线程(非 connect 或 sleep):
- 若只看到 1 个活跃线程,说明并行未启用或已被优化器绕过
- 若看到 2–4 个线程同时执行相同
SELECT,且PROCESSLIST_INFO内容高度相似,基本可断定并行正在工作 - 需提前开启相关 consumer:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE name LIKE 'events_parallel%';
对比 Handler_read_rnd_next 和 Innodb_rows_read 增长速率
并行只加速物理页读取(Handler_read_rnd_next),不影响逻辑处理阶段。通过 SHOW STATUS 对比执行前后指标变化:
- 开启并行后,
Innodb_rows_read应明显快于Handler_read_rnd_next增长——说明数据读取被多个线程分摊 - 若两者增速接近 1:1,说明仍是单线程扫页,
innodb_parallel_read_threads参数未生效或被忽略 - 注意:
innodb_parallel_read_threads是会话级变量,SET SESSION才影响当前连接;SET GLOBAL不改变已有会话











