MySQL 8.0并行扫描需同时满足:显式设置innodb_parallel_read_threads>0、使用EXPLAIN FORMAT=TREE验证、且仅对InnoDB无索引全表扫描生效;不支持聚合、LIMIT、索引查找等常见场景。

MySQL 8.0 升级后,并行查询默认是关闭的,必须显式设置 innodb_parallel_read_threads > 0 才可能启用——但仅设参数还不够,它只对特定场景生效,多数人调了没效果是因为没满足触发条件。
为什么 SET innodb_parallel_read_threads=4 后 EXPLAIN 看不到 parallel?
因为普通 EXPLAIN(包括 EXPLAIN FORMAT=JSON)完全不显示并行信息。只有 EXPLAIN FORMAT=TREE 的输出里出现 Parallel scan on table_name 才算真正启用。
- 执行前务必用
EXPLAIN FORMAT=TREE SELECT ...验证,而不是依赖EXPLAIN或执行时间猜测 - 常见误判:看到查询变快了,就以为是并行起效——实际可能是 buffer pool 预热、查询缓存(已移除)、或 SSD 随机读优化带来的假象
- 如果输出里只有
-> Table scan on table_name,说明并行根本没触发,参数设置无效
哪些查询能触发 innodb_parallel_read_threads?
并行扫描不是“所有大表 SELECT 都自动并行”,它只在极少数无索引、无过滤、无聚合的全表扫描中激活:
- 必须是 InnoDB 表,且走的是聚集索引全扫(即无 WHERE 条件,或 WHERE 条件无法使用任何索引)
- 不支持
LIMIT、ORDER BY、GROUP BY、DISTINCT、子查询、窗口函数 -
COUNT(*)可以触发(前提是无 WHERE),但COUNT(id)或SUM(salary)在部分版本中不保证并行 - 点查(如
WHERE id = 123)、范围查(如WHERE id BETWEEN 100 AND 200)、IN 查询全部绕过并行机制
如何安全地设置 innodb_parallel_read_threads 值?
值设太高反而拖慢,关键看硬件瓶颈在哪:
- 推荐从
SET SESSION innodb_parallel_read_threads = 4开始测试,再逐步加到 CPU 核数的 1–1.5 倍(例如 16 核设 8–12) - 超过 32 很少有收益,实测中 64 线程比 32 还慢,因线程调度和锁竞争开销盖过了 I/O 并发收益
- SSD 场景下,线程数 > I/O 队列深度(如 NVMe 通常为 64–256)无意义;HDD 下设 2–4 就顶天了
- 注意:该参数是会话级的,
SET GLOBAL会影响新连接,但不会改变已有连接的行为
容易被忽略的硬性限制
即使参数正确、语句符合、EXPLAIN FORMAT=TREE 显示 Parallel scan,仍可能被静默降级:
- 事务隔离级别为
REPEATABLE READ且开启 gap lock 时,并行可能被禁用(InnoDB 内部需保证 MVCC 可见性一致性) - 表上有未提交的写事务(哪怕只是另一会话的 INSERT),并行扫描可能退化为单线程以避免读取未提交数据
- 内存不足时,InnoDB 会自动减少实际使用的并行线程数,
SHOW ENGINE INNODB STATUS的 BUFFER POOL AND MEMORY 段可查实际分配情况 - 小表(如


















