我需要将大量数据插入mySQL。大约500k行,Laravel 5.3
中有关系(困难的部分)桌子是车辆,用户和用户_Vehicle
普通车辆插入阵列看起来像这样:
$vehicles = array();
foreach ($data as $val) {
$temp = array(
'license_plate' => $val->license_plate,
'created_at' => $now,
'updated_at' => $now,
'state_id' => $activeState,
'type_id' => $typeId,
);
array_push($vehicles, $temp);
}
我可以成功插入这样的记录:
$vehicles = array_chunk($vehicles, 10000);
foreach ($vehicles as $key => $vehicle) {
Vehicle::insert($vehicle);
}
插入所有数据和所有内容都需要几秒钟,但是现在我需要与它们添加关系。由于一辆车可以属于许多用户(所有者,驾驶员等),因此我需要将某些用户附加到某些车辆。
现在,当我尝试添加关系时,这是我卡住的地方:
$vehicles = array();
$vehUsers = array();
$users = Users::get();
foreach ($data as $val) {
// Remap data to right structure
$temp = array(
'license_plate' => $val->license_plate,
'created_at' => $now,
'updated_at' => $now,
'state_id' => $activeState,
'type_id' => $typeId,
);
// Search for right user (This part is really slow)
$userId = $users->where('email', $val->email)->first();
if ($userId) {
$userId = $userId->id;
}
array_push($vehicles, $temp);
// Thought that it might help to save them into array for later use
array_push($vehUsers, $userId);
}
但是问题是,我无法像这样插入它们
$vehicles = array_chunk($vehicles, 10000);
foreach ($vehicles as $key => $vehicle) {
Vehicle::insert($vehicle);
// Need to attach user here somehow
}
我需要大量运行它们(在我的情况下为10k),因为1 x插入时间太长
// Insert them and relations one by one and it will take years
foreach ($vehicles as $key => $vehicle) {
$veh = Vehicle::insert($vehicle);
$veh->users()->attach($vehUsers[$key]);
}
我如何批量插入车辆及其关系?
编辑:慢零件正在执行DB查询。我可以等待10-20秒才能完成php以完成项目。
首先,加载所有用户。但仅选择id
和email
:
$users = User::pluck('email', 'id')->toArray();
这将创建一个具有[id => email]
结构的数组。
然后,您将能够使用此数组而无需执行其他查询:
$userId = $users[$email];
然后将bigint
类型的id
列添加到vehicle_user
枢轴表。为此表创建单独的块数组,并使用关系的大量插入而不是使用attach()
方法。
首先,请理解您遵循的技术使您一次又一次地通过$data
循环。为什么?因为...
- 首先是循环进行临时变量。
- 然后第二次插入块的循环。
- 第三次查找用户的循环使用与输入相同的电子邮件,然后选择同一用户的车辆,然后将其与
$user->vehicles()->sync([...Vehicle Ids...]);
同步
仅为所有内容制作一个循环,您可以简单地完成您的工作
foreach($data as $key => $vehicle) {
$vehicle = Vehicle::create([
'license_plate' => $vehicle->license_plate,
'state_id' => $activeState,
'type_id' => $typeId,
]);
$user = User::where('email', $vehicle->email)->first();
$vehicle->users()->attach([$user->id]);
}
请理解,Alterstomany方法实际上并不具有自己的模型,但是对于此类/一次,您可以尝试制作枢轴表模型,然后处理查询。但是,再次可能需要诸如Vehicle::where('license_plate', $val->license_plate)
之类的东西。
注意: - 您可以在循环中执行3个查询。或3用于具有多个查询的循环。我绝对会在这里更喜欢第一个。