Yihui’s Blog

暂不分库分表,单表数据量很大如何优化?

日期:2026-07-11
标签:#面试 #八股 #后端 #MySQL #数据库 #场景题

一句话答案

先优化访问模式而非只看行数:收敛查询、建立合适索引、冷热归档、分区、读写分离和缓存,并通过容量指标判断何时必须拆分。

面试口语版

大表不等于必然慢,关键看工作集、索引高度、扫描量和写入模式。先用慢日志和执行计划优化高频 SQL,避免 SELECT *、深分页和无界查询,建立覆盖核心条件的联合索引并删除冗余索引。历史冷数据按时间归档到历史表或对象存储,必要时使用 MySQL 分区方便裁剪和维护,但分区不是分库。读多可加只读副本和缓存,大报表走 OLAP。最后监控表/索引大小、Buffer Pool 命中、DDL 时间、备份恢复和复制延迟,达到单机边界再规划拆分。

关键细节

  • 索引多会拖慢写入并扩大 Buffer Pool 工作集。
  • 分区键需出现在唯一键约束中,并符合主要查询条件。
  • 在线 DDL 仍可能有元数据锁和额外磁盘压力。
  • 归档必须可审计、可恢复并处理跨冷热查询。

面试官追问

  1. MySQL 分区能替代分库分表吗?
  2. 如何做历史数据归档?
  3. 表有亿级数据但查询仍很快,为什么?

面试官追问参考答案

1. MySQL 分区能替代分库分表吗?

不能。分区仍在同一个 MySQL 实例,共享 CPU、内存、日志和故障域;它主要提供分区裁剪、快速删除和管理便利。单机容量或写吞吐达到上限时仍需拆分或迁移。

2. 如何做历史数据归档?

按主键/时间小批量复制到历史库并校验,再小批删除源数据,控制事务、锁和复制延迟。最好通过分区交换/删除降低成本;应用查询根据时间路由,归档任务幂等且保留审计。

3. 表有亿级数据但查询仍很快,为什么?

B+Tree 高度增长缓慢,若查询高选择性、命中覆盖索引且工作集在 Buffer Pool 中,访问页数仍很少。真正影响性能的是扫描行数、随机 I/O、锁竞争和返回数据量,而非单一总行数。

学习清单

  • 能从访问模式、索引和冷热分层优化。
  • 理解分区的能力边界。
Maintained by · YihuiEdit on GitHub

Keep reading

View all posts