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

如何向数据库插入百万条记录避免系统卡顿与页面无响应

如何向数据库插入百万条记录,避免系统卡顿与页面无响应

核心优化思路

解决这类问题的关键是拆分大任务、降低单次操作的资源占用,同时避免同步阻塞用户请求,具体方案如下:

  1. 分块批量插入
    一次性插入百万条记录会瞬间占用大量数据库连接和服务器内存,将数据拆分成小批次(比如每10000条一批)插入,能显著降低系统负载,避免卡顿。

  2. 异步化处理(可选但推荐)
    如果是Web页面触发的插入操作,建议把插入逻辑放到异步任务(如Laravel Queue)中执行,前端直接返回成功提示,后台异步完成数据插入,彻底避免页面无响应。

PHP(Laravel)实现示例

$rangeNumber = collect(range($validatedDate['from'], $validatedDate['to']));
$collectData = [];

foreach ($rangeNumber as $number){
    $collectData[] = [
        'receive_uuid' => $receiveUUID,
        'region_id' => $regionId,
        'office_id' => $officeId,
        'number' => $prefix.str_pad($number, 7, '0', STR_PAD_LEFT),
        'description' => '',
        'created_at' => Carbon::now(),
    ];
}

// 按10000条数据分块
$dataCollection = collect($collectData)->chunk(10000);

// 关闭查询日志,避免内存溢出
DB::disableQueryLog();

foreach ($dataCollection as $data){
    DB::table('blanks')->insert($data->toArray());
}

session()->flash('MsgSuccess', 'Success');
return $this->redirect(route('blanks'), true);

额外优化建议

  • 事务包裹保证数据完整性:如果需要确保所有数据要么全部插入成功,要么全部回滚,可以用事务包裹分块逻辑:
    DB::beginTransaction();
    try {
        foreach ($dataCollection as $data){
            DB::table('blanks')->insert($data->toArray());
        }
        DB::commit();
    } catch (\Exception $e) {
        DB::rollBack();
        // 此处添加错误处理逻辑
    }
    
  • 队列异步执行:将插入逻辑封装成队列任务,前端无需等待插入完成:
    // 分发队列任务,后台异步执行插入
    InsertBlanksJob::dispatch($validatedDate, $receiveUUID, $regionId, $officeId, $prefix);
    
  • 数据库层面优化:临时关闭unique_checks和foreign_key_checks(插入完成后恢复)、调整innodb_buffer_pool_size参数,能进一步提升插入速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:46:26