如何使用找到的组的新值更新行并使其尽可能快?
Posted
技术标签:
【中文标题】如何使用找到的组的新值更新行并使其尽可能快?【英文标题】:How to update rows with new values for groups found and make this as fast as posible? 【发布时间】:2021-02-15 13:18:21 【问题描述】:我有一张表,其中包含以下字段:id、client_id、visit_id、number_of_visit。
此表可以有 30k 到 100+k 行数据。主键是client_id 和visit_id。 (我不能有这两个值相同的行,但同时 client_id 可以出现超过 1 次具有不同的 visit_id 等等)。
我要做的就是给字段number_of_visit
写值,这个值应该是本次访问的序号(第一次、第二次、第三次等)。我有 visit_id
字段,它实际上是一个很大的数字,我需要将其排序为“ASC”并相应地将值写入number_of_visit
。我有这个:
id client_id visit_id number_of_visit
1 103 10 0
2 103 11 0
3 104 12 0
4 105 13 0
5 105 15 0
6 105 16 0
我想这样做:
id client_id visit_id number_of_visit
1 103 10 1
2 103 11 2
3 104 12 1
4 105 13 1
5 105 15 2
6 105 16 3
我以与visit_id
值在ASC
的顺序相同的顺序从1 到n 将值写入number_of_visit
。
此表可以有超过 1 行具有相同的 client_id,但不能有具有相同的 visit_id 的行,因为一个 visit_id 总是相对于特定的 client_id。我需要获取此表中所有client_id
中的所有visit_id
,并使用代表序列号的数字1、2、3 更新这些行的number_of_visit
字段。 (如果这是第一次访问,或者是第二次、第三次等等......)。
我有这个 php 代码:
$visit_ids = [];
$sql = "SELECT clientID, GROUP_CONCAT(id) as 'visit_ids' FROM table_report GROUP BY clientID";
$stmt = $pdo->prepare($sql);
$stmt->execute();
while ($row = $stmt->fetch())
$visit_ids = explode(',', $row['visit_ids']);
$counter = 1;
foreach ($visit_ids as $id)
$query = "UPDATE table_report SET number_of_visit = :value WHERE id = :id";
$statement = $pdo->prepare($query);
$statement->execute([':value' => $counter, ":id" => $id]);
$counter++;
但主要问题是它太慢了。该表现在包含大约 40k 行,但可能超过 100k+。当它是 40k 时,大约需要一两个小时才能完成。
我能做些什么来加快速度?我在这些字段上有索引。
这里还有 EXPLAIN 输出:
【问题讨论】:
【参考方案1】:使用row_number()
:
select t.*, row_number() over(partition by client_id order by visit_id) number_of_visit
from table_report t
如果您想要update
声明:
update table_report t
inner join (
select id, row_number() over(partition by client_id order by visit_id) number_of_visit
from table_report t1
) t1 on t1.id = t.id
set t.number_of_visit = t1.number_of_visit
【讨论】:
谢谢,这正是我需要的。我实际上很接近,但由于某种原因开始做错事。以上是关于如何使用找到的组的新值更新行并使其尽可能快?的主要内容,如果未能解决你的问题,请参考以下文章
如何使 UIImageView 可点击并使其执行某些操作? (迅速)
如何拥有多个带有标题的 UICollectionView 并使其水平滑动