MySQL 分区表面试考点总结

6次阅读

分区表核心目的是解决大表维护难题而非提升单条查询性能,适用于日志、订单等按时间递增且数据量持续增长的场景。

MySQL 分区表面试考点总结

分区表的核心目的和适用场景

分区表不是为了提升单条查询性能,而是为了解决大表的维护难题。比如删除历史数据、加快特定范围扫描、减少锁竞争。常见于日志表、订单表、监控数据表等按时间递增且数据量持续增长的场景。

mysql 支持的分区类型及选择要点

MySQL 5.7+ 主要支持 RANGE、LIST、HASH、KEY 四种分区方式:

  • RANGE 分区:按连续区间划分,最常用在按时间(如 TO_DAYS(create_time)YEAR(create_time))分月/分年;注意必须是有序、非空、不重叠的表达式。
  • LIST 分区:适用于离散值集合,比如按省份编码、业务线编号;需显式列出每个分区包含的值,新增值前要提前添加分区,否则插入失败。
  • HASH / KEY 分区:用于均衡分布,HASH 基于用户表达式,KEY 基于列(支持非整型);适合按 ID 均匀打散,但无法做范围查询裁剪,且不能直接删除某一批数据。

分区裁剪(Partition Pruning)是怎么工作的

这是分区表发挥价值的关键机制——优化器根据 WHERE 条件自动识别只访问部分分区,跳过无关分区。但前提是条件中使用的列必须是分区键或其确定性表达式:

  • WHERE create_time >= '2024-01-01' 可以裁剪,但 WHERE date(create_time) = '2024-01-01' 通常无法裁剪(函数导致索引失效,也影响分区识别)。
  • 联合分区(如 RANGE + HASH)下,只有第一级分区键参与裁剪;第二级仅用于子分区内部均匀分布。
  • EXPLAIN PARTITIONS 查看实际访问了哪些分区,验证是否生效。

分区表的限制与避坑提醒

很多问题在上线后才暴露,面试常考实际落地难点:

  • 主键/唯一索引必须包含分区键(否则建表报错),这意味着不能对非分区字段单独建唯一约束。
  • 不能跨分区 UPDATE 或 delete 涉及多个分区的行(除非用 REPLACE 或先删后插),批量清理历史数据建议用 DROP PARTITION,比 DELETE 快得多且不锁全表。
  • 分区数不宜过多(官方建议 ≤ 100),否则打开表、DDL、统计信息收集开销明显上升;也不宜过少,失去分区意义。
  • 分区表不等于分库分表,它仍是单机逻辑,无法解决连接数、IO、CPU 瓶颈;高并发写入仍可能成为热点。

如何判断一张表是否适合分区

别一上来就分,先看真实瓶颈:

  • 数据量超过 2000 万行且有明显冷热分离(如只查近 3 个月)?
  • 定期归档/删除旧数据,当前用 DELETE 导致慢查询或长事务?
  • 单表备份恢复耗时太久,想按分区并行导出?
  • 现有索引已优化到极致,但范围查询仍扫大量数据?

如果以上都不满足,分区反而增加复杂度,得不偿失。

text=ZqhQzanResources