Laravel 5散装与关系插入



我需要将大量数据插入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以完成项目。

首先,加载所有用户。但仅选择idemail

$users = User::pluck('email', 'id')->toArray();

这将创建一个具有[id => email]结构的数组。

然后,您将能够使用此数组而无需执行其他查询:

$userId = $users[$email];

然后将bigint类型的id列添加到vehicle_user枢轴表。为此表创建单独的块数组,并使用关系的大量插入而不是使用attach()方法。

首先,请理解您遵循的技术使您一次又一次地通过$data循环。为什么?因为...

  1. 首先是循环进行临时变量。
  2. 然后第二次插入块的循环。
  3. 第三次查找用户的循环使用与输入相同的电子邮件,然后选择同一用户的车辆,然后将其与$user->vehicles()->sync([...Vehicle Ids...]);
  4. 同步

仅为所有内容制作一个循环,您可以简单地完成您的工作

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用于具有多个查询的循环。我绝对会在这里更喜欢第一个

最新更新