跳到主要内容
版本:1.0

海量数据处理

「数据量大的时候怎么处理?」——回答框架:先定位瓶颈在哪(存储层?查询层?写入层?),再按成本从低到高逐层演进。不要一上来就分库分表。

查询侧优化(成本最低,先做)​

  • 索引优化:联合索引遵循最左前缀;等值列在前、范围列在后;用覆盖索引避免回表。
  • 只查需要的列:避免 SELECT *,减少网络与内存开销,才有机会覆盖索引。

深分页优化​

LIMIT 1000000, 10 会扫描并丢弃前 100 万行。两种方案:

-- 方案 A:游标 / 滚动分页(记录上一页最大 id),恒定代价
SELECT * FROM user_visit_log
WHERE user_id = 1001 AND id < #{lastId}
ORDER BY id DESC LIMIT 10;

-- 方案 B:延迟关联(必须跳页时),先在索引上定位主键再回表
SELECT t.* FROM user_visit_log t
JOIN (SELECT id FROM user_visit_log
WHERE visit_time >= '2026-10-27'
ORDER BY id LIMIT 1000000, 10) x ON t.id = x.id;

预聚合​

明细数据只用于审计,统计一律走汇总表(定时任务 / 增量聚合)。这是「访问次数」这类场景的标准答案,详见《访问统计表设计》。

写入侧优化(高吞吐写入)​

  • 异步化:请求线程只写 MQ(或内存队列),消费者批量落库(攒 500 条或每秒一批插入),DB 压力降一个数量级。
  • 批量插入:INSERT ... VALUES (...), (...) 批量写,比循环单条插入快 10 倍以上。
  • 缓冲合并:实时计数先走 Redis INCR,定时任务把 Redis 的值刷进汇总表。

架构侧演进(数据量持续增长)​

手段适用场景要点
读写分离读多写少主库写、从库读;注意主从延迟(写后立即读要走主库)
冷热分离 / 归档历史数据占比高近 3 个月热数据在线,更早的归档到历史表 / 低成本存储
分库分表单表持续超千万且索引、归档仍撑不住垂直拆(按业务)、水平拆(按 user_id 哈希或按时间);引入 ShardingSphere;提前想好跨片查询与分布式 ID
换 OLAP 存储复杂统计分析明细导入 ClickHouse / Doris,统计分析类查询天然快几十倍

:::warning 分库分表是最后手段 单表千万级不是必然要拆——索引合理 + 预聚合 + 归档后,单表几千万也常常够用。分库分表引入即接受复杂度:跨片 join、分布式事务、扩容迁移。面试时先讲「我会先排除索引和统计方式的问题,再谈拆分」。 :::