laravel实现100w大量数据插入数据库

laravel实现100w大量数据插入数据库

在使用laravel eloquent进行数据库操作的时候惊讶的发现这货居然不支持批量添加,看到网上很多人在循环里进行数据库插入操作来实现批量添加,我想说这样做是很损失性能滴!好在框架的DB门面里的insert方法可以进行批量插入。

$data= [
  ['name'=>'111'],
  ['name'=>'222'],
];
DB::table('xxx')->insert($data);

但是我的数据有点多,100w条数据需要导入数据库,一条条插入,需要好久的时间。原生sql可以实现拼接语句实现批量执行达到快速导入的效果。在laravel框架中貌似要自己实现,查找发现集合的chunk方法实现数据分块处理,达到组装批量插入效果。代码如下:

 set_time_limit(0);

 try {
    //上传文件位置,这里默认是在storage中,如有修改请对应替换
    $file = storage_path('/app/public/' . $input['file']);
    $domain = [];
    foreach($this->readTxt($file) as $key=>$line) {
        $domain[$key] = $line;
    }
    //数组分块处理
    $chunck = collect($domain);
    $chunks = $chunck->chunk(1000);
    $chunks->all();
    foreach ($chunks as $key=>$val){
        $arr = [];
        foreach ($val as $k =>$value){
            $arr[$k]['domain'] = $value;
            $arr[$k]['created_at'] = date('Y-m-d H:i:s');
        }
        DB::table('domain')->insert($arr);
   }
 }catch (\Exception $e) {
    return $this->response()->error($e->getMessage());
 }

读文件使用的方法:

  public function readTxt($path)
    {
        $file = fopen($path, "r");
        //输出文本中所有的行,直到文件结束为止。
        while (!feof($file)) {
            yield trim(fgets($file));  //迭代器,
        }
        fclose($file);
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
知者不惑,仁者不忧,勇者不惧。
本帖由系统于 2周前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 42

@诺大的院子 加上事务为什么会快啊?

2个月前 评论
AppModel::query()->insert([
  ['name'=>'111'],
  ['name'=>'222']
]);

这样不能批量添加?

2个月前 评论
shaolin (作者) 2个月前
shaolin (作者) 2个月前
huangxu (楼主) 2个月前
huangxu (楼主) 2个月前
huangxu (楼主) 2个月前
laradocs 2个月前

所以你这样插入100万条花了多久时间?

2个月前 评论
吃鱼不吐刺 (作者) 2个月前
huangxu (楼主) 2个月前
huangxu (楼主) 2个月前
mysql cli source 100w.sql  🐶
2个月前 评论
huangxu (楼主) 2个月前
心语难诉 2个月前

先关闭数据库的 autocommit,再用 LazyCollection,然后再根据内存情况选择每次插入的量,最后批量插入

另外

MySQL 自带的 LOAD DATA 指令轻轻松松加载千万级别的数据

dev.mysql.com/doc/refman/8.0/en/lo...

2个月前 评论

数据读取有内存过大的风险 建议用生成器

2个月前 评论
huangxu (楼主) 2个月前

两万的数据 分块(1000)插入数据库 时间一分钟多直接报超时 怎么解决

1个月前 评论
huangxu (楼主) 1个月前

@huangxu 是这样的 麻烦看一下是否还有优化空间 谢谢

file

1个月前 评论
shaolin 1个月前
shaolin 1个月前
shaolin 1个月前
SmileVV (作者) 1个月前
shaolin 1个月前
SmileVV (作者) 1个月前
shaolin 1个月前
shaolin 1个月前
SmileVV (作者) 1个月前
SmileVV (作者) 1个月前
SmileVV (作者) 1个月前
飞飞鱼 1个月前

有点狠,100W行的文件读出来,放到php数组,光这一步估计内存就要扛不住了,再把数组转换成collection对象,想想都可怕......

建议使用生成器读取文件,读取同时分批生成collection或者分批写入数据库,这样稍微好些

1个月前 评论
huangxu (楼主) 1个月前

技术文章也开始标题党了

1个月前 评论
huangxu (楼主) 1个月前

代码的意思是100W行数据要放在数据?确定内存没压力吗

1个月前 评论
huangxu (楼主) 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!