在 Laravel 中插入数据的最快方法

Sta*_*tar 1 php sql optimization laravel

我制定了一种复制分支用户权限的方法。权限通常为 0 到 120 项。运行此方法将此(0 到 120)项插入到 7 个 user_ids 需要 35-55 秒才能插入到表中。

/**
 * Copy Branch User Permissions
 *
 * @param Int
 * @param Int
 * @param Int
 * @return Array
 */
public function copyBranchUserPermissions($branchIdFrom, $branchIdTo, $userId)
{
    $permissions = BranchPermissionUser::get()
        ->where('branch_id', $branchIdFrom)
        ->where('user_id', $userId);

    foreach($permissions as $permission) {
        $permission->create([
            'branch_id' => $branchIdTo,
            'permission_id' => $permission->permission_id,
            'user_id' => $userId
        ]);
    }

    return $permissions;
}
Run Code Online (Sandbox Code Playgroud)

由于插入数据的性能缓慢,我需要优化这个过程。我在想如果超过 10 个用户怎么办,所以这个过程会花太长时间。有什么办法可以提高插入数据的性能速度吗?

先感谢您!

Anu*_*tha 7

如果您非常需要速度优化,最好坚持使用查询生成器,而不是采用 Eloquent 方式。

欲了解更多信息: Laravel Eloquent vs 查询生成器 - 为什么使用 eloquent 来降低性能

当您获取用户和分支特定的权限时

 $permissions = BranchPermissionUser::get()
    ->where('branch_id', $branchIdFrom)
    ->where('user_id', $userId);
Run Code Online (Sandbox Code Playgroud)

您首先从数据库表中加载所有数据,并对所有数据生成的集合执行 where 操作。

您应该在 get 方法之前执行 where 条件,这样它将在 SQL 端进行处理,这比在从get eloquent 方法创建的集合中执行要快得多。

$permissions = BranchPermissionUser::query()
                        ->where('branch_id', $branchIdFrom)
                        ->where('user_id', $userId)
                        ->get();
Run Code Online (Sandbox Code Playgroud)

此外,您还循环遍历所有权限并在数据库中创建每一项权限。

 foreach($permissions as $permission) {
    $permission->create([
        'branch_id' => $branchIdTo,
        'permission_id' => $permission->permission_id,
        'user_id' => $userId
    ]);
Run Code Online (Sandbox Code Playgroud)

这会为每个创建创建一个查询。这非常慢,并且不是同时保存多行数据的最佳实践。

您应该使用insert方法插入所有行,这会创建单个 SQL 查询,并且速度更快且经过优化。

注意:插入行时,Insert 方法不会处理created_at 和updated_at 字段。因此,您必须手动为它们添加数据。

$data=[];
foreach($permissions as $permission) {
  $data[] = [
    'branch_id' => $branchIdTo,
    'user_id' => $userId,
    'permission_id' => $permission->permission_id,
    'created_at' => now(),
    'updated_at' => now(),
  ];
}
BranchPermissionUser::insert($data);
Run Code Online (Sandbox Code Playgroud)

now()是一个 Laravel 助手,它为当前时间创建一个新的 Carbon 实例:。