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 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
关于 LearnKu
高认可度评论:
集合《Laravel 8 中文文档》
@诺大的院子 加上事务为什么会快啊?
这样不能批量添加?
所以你这样插入100万条花了多久时间?
先关闭数据库的 autocommit,再用 LazyCollection,然后再根据内存情况选择每次插入的量,最后批量插入
另外
MySQL 自带的 LOAD DATA 指令轻轻松松加载千万级别的数据
dev.mysql.com/doc/refman/8.0/en/lo...
数据读取有内存过大的风险 建议用生成器
两万的数据 分块(1000)插入数据库 时间一分钟多直接报超时 怎么解决
@huangxu 是这样的 麻烦看一下是否还有优化空间 谢谢
有点狠,100W行的文件读出来,放到php数组,光这一步估计内存就要扛不住了,再把数组转换成collection对象,想想都可怕......
建议使用生成器读取文件,读取同时分批生成collection或者分批写入数据库,这样稍微好些
技术文章也开始标题党了
代码的意思是100W行数据要放在数据?确定内存没压力吗
domain,达咩~
下面只是我看代码的分析,没有做实际测试
你这不还是长时间占用I/O开销。这也算方法!!!