MySQL 26.10 让 EXPLAIN TREE 和 JSON v2 输出显示分区裁剪结果
MySQL 26.10.0 的 release notes(2026-10-20)里有一条与 EXPLAIN 直接相关的改动:基于迭代器的 EXPLAIN 输出开始报告分区裁剪结果。传统 EXPLAIN 的 partitions 列一直有这项信息,缺的是 FORMAT=TREE、EXPLAIN ANALYZE 和 JSON v2。
26.10.0 release notes 中的三条
分区可见性(WL #17309)
Iterator-based EXPLAIN 输出现在会报告在显式 PARTITION(...) 限制和优化器裁剪之后选中的分区:
EXPLAIN FORMAT=TREE和支持的EXPLAIN ANALYZE计划,把分区名写进操作文本;- JSON v2 提供一个结构化的
partitions数组; - 适用于受支持的 InnoDB 和 NDB 基表访问;
- 表示的是计划期候选读集(plan-time candidate read set),不是运行期实际访问的分区;
- 传统 EXPLAIN 和 JSON v1 不变。
AUTO_INCREMENT 参与分区表达式时的分区锁(Bug #109601、Bug #34972980)
分区表的 INSERT 在 AUTO_INCREMENT 列参与分区表达式时,可能访问并锁住所有分区,即使每一行都提供了显式的确定值。现在当每个值都是常量、非 NULL、且不是自动生成的 zero 时,分区裁剪会正常进行。值非常量、为 NULL 或为 zero 时裁剪仍然关闭,除非 NO_AUTO_VALUE_ON_ZERO 生效。致谢 Hope Lee。
WEEDOUT 缺 access_type(Bug #37925474)
当 explain_json_format_version=2 时,WEEDOUT AccessPath 的 EXPLAIN 输出缺少 access_type 属性。
背景:早就有的是传统 EXPLAIN 的 partitions 列
对应提案是 mysql/mysql-community issue #36 “Partition Pruning Visibility in Iterator-Based EXPLAIN Output”,最初由 Øystein Grøvlen 提交,bug 号为 120451。
现状是分裂的:传统 EXPLAIN 已经在 partitions 列报告选中的分区,legacy JSON EXPLAIN 通过 partitions 属性暴露同样的信息。树形 EXPLAIN 输出(包括 hypergraph 计划和 EXPLAIN ANALYZE)缺这块信息;新的迭代器 JSON 格式(JSON format version 2 与 hypergraph JSON 输出使用)也没有暴露。这次改动让分区信息出现在树形 EXPLAIN 和相关表访问节点上,也让新 JSON 格式带上它,使各 EXPLAIN 格式对分区裁剪的可见性一致。
实际输出位置可以这样记:
EXPLAIN FORMAT=TREE -> 分区名出现在表访问节点的 operation text 里
EXPLAIN ANALYZE -> 同上(受支持的计划)
JSON v2 -> "partitions": [ ... ] 结构化数组
EXPLAIN(传统表格) -> partitions 列(未变)
JSON v1 -> partitions 属性(未变)
分区裁剪规则回顾(26.10 手册 26.4)
概念一句话:“Do not scan partitions where there can be no matching values”。
手册示例表:
CREATE TABLE t1 (
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
region_code TINYINT UNSIGNED NOT NULL,
dob DATE NOT NULL
)
PARTITION BY RANGE( region_code ) (
PARTITION p0 VALUES LESS THAN (64),
PARTITION p1 VALUES LESS THAN (128),
PARTITION p2 VALUES LESS THAN (192),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
查询:
SELECT fname, lname, region_code, dob
FROM t1
WHERE region_code > 125 AND region_code < 130;
只需要扫描 p1 和 p2。
优化器能在 WHERE 条件归约为 partition_column = constant 或 partition_column IN (constant1...constantN) 时裁剪;<、>、<=、>=、<> 在很多情况下也可用;短区间会被转换成 IN 列表。
使用 YEAR() 或 TO_DAYS()(以及 TO_SECONDS())作为分区表达式的 DATE/DATETIME 分区同样支持裁剪。
针对分区表的 WHERE 条件里出现非法 DATE/DATETIME 值时,会被当作 NULL 处理(Bug #40972),所以:
SELECT * FROM partitioned_table WHERE date_column < '2008-12-00';
返回空结果。
HASH / [LINEAR] KEY 分区只在针对分区表达式列的简单等值条件上可裁剪;短区间只有在区间大小小于分区数量时才转成 IN;且只对整数列裁剪。
RANGE 分区表自查流程
用上面的 t1 和那条 region_code > 125 AND region_code < 130 查询:
- 先跑传统
EXPLAIN,看partitions列是不是p1,p2。这是基线,格式没变。 - 再跑
EXPLAIN FORMAT=TREE,看表访问节点的操作文本里有没有出现p1、p2这两个分区名。26.10 之前这里看不到。 - 需要实际执行时用
EXPLAIN ANALYZE,同样在操作文本里找分区名;注意 ANALYZE 的 actual 行数不能用来反推分区是否被物理读取。 - 需要程序解析时用 JSON v2(
explain_json_format_version=2),读partitions数组,而不是去正则匹配文本。 - 如果 TREE 里没有分区名:确认语句是否被裁剪(对照第 1 步的
partitions列)、是否有显式PARTITION(...)限制、以及该访问是否属于受支持的表访问类型(InnoDB / NDB 基表访问)。
第 2 步和第 4 步看到的都是计划期候选读集,不等于运行期实际访问的分区集合。
26.10 其它变更
来自 Oracle 博客 MySQL October 2026 GA Releases(Mike Frank,2026-10-21):
- 四段式版本号
MAJOR.MINOR.PATCH.UPDATE,配套VERSION_WITH_UPDATE()与@@version_with_update; - Community Edition 增加 Health Monitor 组件(Linux/macOS,磁盘/内存/CPU,磁盘预测,fencing 默认关闭);
- MySQL REST Service 作为 MySQL Server 组件提供,不再需要单独的 MySQL Router 进程,HTTPS 端点带 TLS 证书、worker 线程、连接数限制、请求/响应大小限制;
- 分区裁剪可见性改进(即上文 WL #17309);
- JSON Duality Views 的
CHECK/NO CHECK与UPDATE/NO UPDATE注解; - InnoDB REDO 解析缓存索引元数据;
- MySQL Router 可通过
mysqlrouter --reload-tls在不重启的情况下重载 TLS 材料。
链接
- Release notes:https://dev.mysql.com/doc/relnotes/mysql/26.10/en/news-26-10-0.html
- 手册 26.4 Partition Pruning:https://dev.mysql.com/doc/refman/26.10/en/partitioning-pruning.html
- 提案 issue #36:https://github.com/mysql/mysql-community/issues/36
- Oracle 博客:https://blogs.oracle.com/mysql/mysql-october-2026-ga-releases-now-available