【发布时间】:2020-01-13 21:13:14
【问题描述】:
我的user_level数据库结构是
| user_id | level |
| 3 | F |
| 4 | 13 |
| 21 | 2 |
| 24 | 2 |
| 33 | 3 |
| 34 | 12+ |
我还有一张桌子users
| id | school_id |
| 3 | 3 |
| 4 | 4 |
| 21 | 2 |
| 24 | 2 |
| 33 | 3 |
| 34 | 1 |
我必须实现的是,我必须根据某个预定义条件更新每个用户的level。但是,我的 users 表非常庞大,有数千条记录。
在一个实例中,我只更新特定学校的user_level 记录。比如说school_id = 3,我获取所有用户及其关联的等级,然后将这些用户的等级值增加1(F变为1,删除12+,所有其他数字都增加1)。
当我使用循环遍历用户时,匹配他们的user_id 然后更新记录,这将是数千个查询。这会降低整个应用程序的速度并导致其崩溃。
一个理想的事情是 laravel 交易,但我怀疑它是否优化了时间。我在一个包含大约 6000 条记录的简单查询中对其进行了测试,它运行良好。但是由于某种原因,它对我的记录没有那么好。
只是看一些关于任何其他查询优化技术的建议。
更新
我实现了一个解决方案,我将根据级别对所有记录进行分组(使用 laravel 集合),然后我只需要发出 13 个更新查询,而现在有成百上千个。
$students = Users::where('school_id', 21)->get();
$groupedStudents = $students->groupBy('level');
foreach ($groupedStudents as $key => $value) :
$studentIDs = $value->pluck('id');
// condition to check and get the new value to update
// i have used switch cases to identify what the next level should be ($NexLevel)
UserLevel::whereIn('userId', $studentIDs)->update(["level" => $nextLevel]);
endforeach;
我仍在寻找其他可能的选择。
【问题讨论】:
-
在一条 SQL 语句中进行更新,而不是无数次不同的更新。这通常更快。
-
@GordonLinoff 更多见解。不过,我将不得不遍历所有记录以检查条件。