You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel-Excel 2 大批量Excel数据入库提速方法咨询

优化Laravel-Excel 2处理百万级Excel导入的方案

针对你遇到的140万行大型Excel导入性能瓶颈,我分享几个亲测有效的优化思路,以及对你已验证分块方案的补充优化:

核心优化建议

  • 批量插入替代单条插入:原来循环里每次insert单条数据,会频繁触发数据库交互,性能极低。攒一批数据(比如100-500条)再批量插入,能大幅减少数据库连接次数,这是提升速度的核心。
  • 分块处理避免内存溢出:把大数据集拆成小chunk,既控制单次插入的数据量,也避免一次性加载全量数据导致内存耗尽——你已经用了这个方案,效果确实明显。
  • 流式读取(内存友好型方案):不要一次性把整个Excel转成数组,用Laravel-Excel的each方法逐行读取处理,边读边攒批量数据,内存占用会非常低,完美适配百万级数据。
  • 数据库层面优化:
    • 保持事务包裹批量操作(你已经在做了),避免部分插入失败导致数据不一致;
    • 临时关闭外键检查(如果表有外键约束):DB::statement('SET FOREIGN_KEY_CHECKS=0;'),插入完成后再开启;
    • 禁用自动提交:DB::statement('SET AUTOCOMMIT=0;'),事务结束后恢复默认设置。
  • 多工作表分批处理:如果有多个工作表,循环遍历每个工作表单独处理,不要一次性加载所有工作表的数据。

你验证有效的分块处理代码(格式化版)

$data = Excel::selectSheetsByIndex(0)->load($file, function($reader) {})->get()->toArray();

DB::beginTransaction();
try {
    $bulk_data = [];
    foreach ($data as $key => $value) {
        $med = trim($value["med"]);
        $serial = trim($value["nro.seriemedidor"]);
        $bulk_data[] = ["med" => $med,"serial_number" => $serial];
    }

    $collection = collect($bulk_data);
    $chunks = $collection->chunk(100); // 按100条分块处理

    foreach($chunks as $chunk) {
        DB::table('medidores')->insert($chunk->toArray());
    }

    DB::commit();
} catch (\Exception $e) {
    DB::rollback();
    return redirect()->route('myroute')->withErrors("导入失败:" . $e->getMessage());
}

更适配百万级数据的流式读取方案

如果140万行数据一次性转成数组仍会出现内存溢出,试试流式逐行处理,不需要把全量数据加载到内存:

DB::beginTransaction();
try {
    $bulk_data = [];
    $chunkSize = 100; // 每100条执行一次批量插入

    Excel::selectSheetsByIndex(0)->load($file, function($reader) use (&$bulk_data, $chunkSize) {
        // 逐行遍历Excel数据
        $reader->each(function($row) use (&$bulk_data, $chunkSize) {
            $med = trim($row->med);
            $serial = trim($row->get('nro.seriemedidor'));
            $bulk_data[] = ["med" => $med, "serial_number" => $serial];

            // 达到设定的批量数就插入并清空数组
            if (count($bulk_data) >= $chunkSize) {
                DB::table('medidores')->insert($bulk_data);
                $bulk_data = [];
            }
        });
    });

    // 处理最后一批不足批量数的数据
    if (!empty($bulk_data)) {
        DB::table('medidores')->insert($bulk_data);
    }

    DB::commit();
    return redirect()->route('myroute')->withSuccess("导入成功!");
} catch (\Exception $e) {
    DB::rollback();
    return redirect()->route('myroute')->withErrors("导入失败:" . $e->getMessage());
}

这个方案的优势是内存占用极低,不管Excel有多少行,都不会因为加载全量数据导致内存溢出,是超大型文件导入的最优解。

内容的提问来源于stack exchange,提问作者pmiranda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:27:50