Pstart和Pstop是优化器决定访问的物理分区编号范围,若二者相等且对应目标分区编号则裁剪生效,若Pstart=1、Pstop=N则全分区扫描;需结合SHOW CREATE TABLE确认编号映射,并避免对分区键使用函数。
怎么看 EXPLAIN 里的 Pstart 和 Pstop 是否合理
分区裁剪是否生效,最直接的证据就藏在 explain 输出的执行计划中——特别是 pstart(partition start)和 pstop(partition stop)两列。它们不是“扫描起止时间”,而是优化器决定访问的**物理分区编号范围**。
比如你建了按年分区的表,共 4 个分区:p2021、p2022、p2023、p2024,对应内部编号可能是 1~4。当你查 2023 年数据时,理想输出是:
| id | select_type | table | partitions | Pstart | Pstop | ... | |----|-------------|---------|------------|--------|--------|-----| | 1 | SIMPLE | orders | p2023 | 3 | 3 | ... |
这说明只访问第 3 号分区(即 p2023)。如果看到 Pstart=1 且 Pstop=4,就是全分区扫描,裁剪失败。
-
Pstart和Pstop是整数索引,不是分区名;要对照SHOW CREATE TABLE或INFORMATION_SCHEMA.PARTITIONS查编号映射 - MySQL 5.7+ 默认在
EXPLAIN FORMAT=TREE中不显示这两列,必须用EXPLAIN FORMAT=TRADITIONAL或老式文本格式 - 若
partitions列为空或显示NULL,大概率裁剪没触发,别信rows估算值
为什么 WHERE 条件写了分区键,Pstart/Pstop 还是全量?
写对了字段名、也用了等值条件,但 Pstart=1、Pstop=N,常见原因不是语法错,而是语义“不可推导”。
- 分区键被函数包裹:
WHERE YEAR(order_date) = 2023→ 优化器无法反推日期范围,裁剪失效;应改用order_date >= '2023-01-01' AND order_date - 隐式类型转换:
dt是STRING分区列,却写WHERE dt = 20230101→ MySQL 会把分区值转成数字比较,破坏分区元数据匹配 - 使用了非确定性函数:
WHERE dt = CURDATE()或dt = DATE_SUB(NOW(), INTERVAL 1 DAY),部分版本(如 MySQL 8.0.33 前)不支持运行时裁剪,Pstart/Pstop仍为全量 - 分区表达式与查询条件不一致:比如按
TO_DAYS(order_date)分区,但 WHERE 里用的是order_date >= '2023-01-01'—— 看似合理,实际依赖优化器能否将常量日期准确映射到TO_DAYS值,有版本兼容风险
EXPLAIN PARTITIONS 和普通 EXPLAIN 的关键区别
MySQL 中只有显式加上 PARTITIONS 关键字,才会在执行计划中输出 partitions、Pstart、Pstop 这些列。漏掉这个关键词,等于关掉了分区裁剪的“诊断开关”。
- 错误写法:
EXPLAIN SELECT * FROM orders WHERE order_date >= '2023-01-01';→ 不显示分区信息 - 正确写法:
EXPLAIN PARTITIONS SELECT * FROM orders WHERE order_date >= '2023-01-01';→ 显示partitions列及Pstart/Pstop - 注意:
EXPLAIN FORMAT=TREE不支持PARTITIONS,二者互斥;需要看裁剪,就老实用传统格式 - 在慢查询日志或 Performance Schema 中,
EXPLAIN记录默认不含分区信息,必须主动补上PARTITIONS才能归因
除了 Pstart/Pstop,还有哪些信号说明裁剪可能假阳性
有时 Pstart=Pstop 看着很完美,但实际性能没提升,甚至更差——说明裁剪“形式上成功”,但底层没省 IO。
- 分区本身为空:
Pstart=Pstop=3,但p2023是空分区,扫描开销极小,容易误判为“裁剪有效” - 分区数据极度倾斜:比如
p2023存了全表 95% 的数据,虽然只扫一个分区,IO 量并没降多少 - 用了全局二级索引(GSI):MySQL 8.0+ 支持全局索引,但裁剪逻辑可能绕过分区判断,导致
Pstart/Pstop正常,实际仍走索引全扫 - 查询含
FORCE INDEX:人为指定索引可能干扰优化器对分区的决策路径,使Pstart/Pstop失真
真正可靠的验证方式,是结合 Handler_read_* 状态变量(如 Handler_read_next)或磁盘 IO 监控,看实际读取的数据页是否与目标分区规模匹配。光盯 Pstart/Pstop 容易被表象骗过去。










