在仅有 100M 内存限制的环境下,用 PHP 查询数据库并把 100W 行数据导出成 CSV 文件,你会怎么设计和实现?请说明关键步骤与注意事项。
考察说明
考查大数据量导出时对内存控制、分批处理、数据库游标及文件写入流的使用。
回答思路
- 【回答框架 1】核心是避免一次性加载全部数据到内存。使用数据库查询的游标或分批查询方式,例如利用 LIMIT 和 OFFSET 或基于 ID 范围分段取数,每次只处理一部分行。
- 【回答框架 2】在 PHP 中,采用生成器(yield)逐行遍历结果集,配合数据库驱动(如 PDO 或 mysqli 的 unbuffered query)以流式获取数据,避免将整个结果集缓存在内存。
- 【回答框架 3】写入 CSV 时使用 SplFileObject 或 fputcsv 直接向文件句柄追加写入,每处理一行立即 flush,避免在内存中组装整个文件内容。
- 【回答框架 4】对于 100W 行数据,可设置每批 1000 行,循环执行查询与写入,同时监控内存使用(memory_get_usage),确保峰值不超过限制。
- 【回答框架 5】考虑执行时间与脚本超时,建议通过 CLI 运行或分段脚本,必要时使用临时文件分块合并。
- 【关键点 1】使用流式查询或分批 LIMIT 避免全量加载
- 【关键点 2】结合生成器逐行处理结果集
- 【关键点 3】用 fputcsv 实时写入文件并及时释放内存
- 【关键点 4】评估 total time 与 memory 峰值,必要时调整批次大小
- 【易错点 1】误用 buffered query 导致内存耗尽
- 【易错点 2】忽略 OFFSET 深翻页性能问题,建议改用 ID 或时间戳游标
- 【易错点 3】未设置脚本运行时间限制导致中断