使用数据库的原生批量加载路径(Postgres COPY、MySQL LOAD DATA),把文件切成多个分块,并行加载到一张禁用了 index 和约束的,使崩溃后能恢复而不重复插入行。
100M-row CSV
│ split by byte offset
▼
[chunk 1] [chunk 2] ... [chunk N] N parallel workers
│ │ │
└──── COPY / LOAD DATA (no indexes) ────▶ staging_table (UNLOGGED)
│
rebuild indexes + validate
│
INSERT ... SELECT (upsert) into target
对每一行做一个朴素的 INSERT,要付出一次往返、一次解析、一次 WAL/redo 写入和一次 index 更新,共 1 亿次。即便每次只要 1ms,那也超过一天。批量路径通过摊薄所有这些而胜出:COPY 在一条协议消息中流式传输行,批量处理 WAL,并跳过逐语句的规划(planning)。在真实硬件上,单个 COPY 能达到每秒 10 万–50 万行,而 INSERT 只有每秒几千行。
UNLOGGED 完全跳过 WAL),绝不直接进线上表。这把加载与读者隔离,并让你能在发布前进行验证。CREATE INDEX——批量(排序)构建 index 远比 1 亿次增量更新便宜。COPY 流。throughput 随 I/O 和 CPU 扩展,直到你让磁盘或 WAL 饱和。让 N 匹配核数/IOPS,而非"越多越好"。INSERT ... ON CONFLICT DO NOTHING/UPDATE(upsert)发布,使重跑绝不会重复插入。面试官在检查你是否知道批量路径的存在以及它为什么快数个数量级——而不是 COPY 语法。好:"用 COPY"。出色:"COPY 进一张 UNLOGGED 暂存表,删掉 index,并行分块,之后重建,用 upsert 发布,按分块 id 可恢复。"经典陷阱是循环 INSERT(或 ORM 的 saveAll)然后惊讶于它要花数小时;第二个陷阱是直接加载进线上表并阻塞生产。
maintenance_work_mem/临时空间;一次 1 亿行的 index 构建可能会溢写到磁盘。一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠