MySQL 8.0.30+ 并行查询为实验性功能,默认关闭,仅适用于单表全表或范围扫描,需同时启用parallel_query、parallel_threads_limit和innodb_parallel_read_threads三个参数才生效。

MySQL 8.0+ 并行查询到底开不开得起来
MySQL 原生并行查询(Parallel Query)仅在 MySQL 8.0.30+ 版本中以实验性功能引入,且**默认完全关闭**,不依赖 CPU 核数自动启用。它只作用于特定场景:单表 SELECT 扫描(无 JOIN、无子查询、无 GROUP BY / ORDER BY),且必须走全表扫描或范围扫描的 InnoDB 表。不是“开了就快”,更不是“多核自动加速”。
怎么打开并行查询:三个必要参数缺一不可
并行查询由三个系统变量协同控制,少一个都无效:
-
parallel_query:全局开关,设为ON(默认OFF) -
parallel_threads_limit:单查询最多用几个工作线程(含主线程),建议设为2~4(不是 CPU 核数!设太高反而因调度开销拖慢) -
innodb_parallel_read_threads:InnoDB 层并行读线程数,必须 ≥parallel_threads_limit - 1(因为主线程占 1 个)
示例设置(需重启或动态 SET GLOBAL,后者对已连接会话不生效):
SET GLOBAL parallel_query = ON; SET GLOBAL parallel_threads_limit = 3; SET GLOBAL innodb_parallel_read_threads = 2;
注意:parallel_threads_limit = 3 意味着最多启用 2 个额外工作线程(主线程 + 2 并行线程),总并发读线程数 = 3。
为什么 EXPLAIN 看不到并行,但实际跑了?
MySQL 不会在 EXPLAIN 输出中显示“Using parallel scan”之类提示。判断是否真正并行,只能靠:
- 开启
performance_schema后查events_statements_history_long,看SOURCE列是否含sql/par_parser.cc或sql/parallel_reader.cc - 监控
SHOW PROCESSLIST,执行中若出现多个parallel read thread状态的线程(非用户连接),说明已触发 - 对比开启前后
sys.schema_table_statistics_with_buffer中相同查询的rows_examined和耗时 —— 并行只减少 CPU-bound 扫描时间,对 I/O-bound 场景几乎无改善
常见误判:看到 CPU 使用率升高 ≠ 并行生效;可能是缓冲池争用或锁等待导致线程堆积。
比并行查询更实用的多核利用方式
对绝大多数 OLTP 或混合负载,盲目开并行查询收益极低,反而增加内存与锁竞争。真正释放多核能力的常规做法是:
- 提高
innodb_read_io_threads和innodb_write_io_threads(如设为4~8),让 InnoDB 更充分使用磁盘 I/O 并发能力 - 确保
innodb_buffer_pool_instances≥ CPU 核数 / 2(但不超过 64),降低 buffer pool 全局互斥锁争用 - 用
thread_pool_size(Percona Server / MySQL 8.0.31+ Enterprise)替代默认连接模型,避免大量短连接打满线程创建开销 - 把大查询拆成多个可并行的独立
SELECT,由应用层分发到不同连接 —— 这比单语句并行更可控、兼容性更好
并行查询是个窄口径优化点,容易被文档误导。实际调优时,先确认是不是真卡在单表全扫上,再检查 buffer pool 命中率和 I/O 能力 —— 多数时候,加内存、调缓冲池、优化索引,比折腾并行参数见效快得多。


















