分区表未提速通常因查询未匹配分区键导致裁剪失效,需用EXPLAIN PARTITIONS验证;WHERE条件须含裸分区键等值或范围匹配,主键必须包含分区键,JOIN时ON条件也需含分区键等值匹配。

分区表没变快,大概率不是分区本身有问题,而是查询条件没“对上”分区键——MySQL根本没跳过无关分区,白拆了。
EXPLAIN PARTITIONS 看清到底扫了几个分区
别猜,直接查执行计划。加 PARTITIONS 关键字才能看到真实分区访问情况:
EXPLAIN PARTITIONS SELECT * FROM orders WHERE user_id = 123;
如果 partitions 列显示 p202101,p202102,...,pmax 全部列出,说明没裁剪,全扫;只出现 p202607 这种单个或少数几个,才算真正生效。
- 没裁剪时,性能通常比单表还差——多了一层元数据调度开销
-
Handler_read_next远高于Handler_read_rnd_next是裁剪有效的信号 - 注意:
SELECT COUNT(*)或无 WHERE 条件的查询,永远全扫
WHERE 条件必须含分区键,且不能套函数
分区裁剪只认“裸字段”的等值或范围匹配。哪怕只多包一层函数,就失效:
- ❌
WHERE DATE(created_at) = '2024-01-01'→ 全扫 - ✅
WHERE created_at >= '2024-01-01' AND created_at → 可裁剪 - ❌
WHERE YEAR(created_at) = 2024→ 函数包裹,索引和分区都失效 - ✅
PARTITION BY RANGE COLUMNS(created_at)+ 上面那个范围写法,最稳
IN 查询慢?检查主键是否包含分区键
用 id IN (1,2,3) 查得慢,往往因为 id 不是分区键,而分区键是 created_at ——MySQL无法从 id 推出该去哪个分区。
- 要让
IN走裁剪,要么把id设为分区键(不推荐,破坏时间局部性) - 要么改成带分区键的组合条件:
WHERE id IN (1,2,3) AND created_at >= '2026-08-01' - 更关键的是:主键必须包含分区键,否则
UPDATE/DELETE会退化为全表扫描
JOIN 时分区表被当普通表用了
和非分区表 JOIN,或者 ON 条件没包含分区键,优化器大概率放弃裁剪:
- ❌
JOIN order_items ON orders.id = order_items.order_id→ 若order_items未按相同键分区,orders 表的分区失效 - ✅ 把分区表当驱动表,且
ON中含分区键等值匹配:JOIN order_items ON orders.created_at = order_items.created_at AND orders.user_id = order_items.user_id - 统计信息不一致时,
ANALYZE TABLE比重启更管用
分区不是银弹,它只加速“能定位到具体分区”的查询。一旦业务查询模式和分区设计错位,性能反而更差——这点比索引失效更隐蔽,因为表结构看着很“高级”。


















