使用不同的列集更有效地更新大量行?

Posted

技术标签:

【中文标题】使用不同的列集更有效地更新大量行?【英文标题】:Updating Large Amount Of Rows With Different Sets Of Columns More Efficiently? 【发布时间】:2020-03-05 21:50:27 【问题描述】:

我需要在 mysql 表中更新 10,000 行,并且我需要为每一行更新一组不同的列(例如,有些行需要更改用户名,有些行需要更改电话号码,还有一些行都需要更改)。我需要能够在 10 分钟内更新这 10,000 行,这就带来了问题:

我目前正在为每一行执行单独的更新查询(使用 PDO),通过 10,000 个单独的查询更新 10,000 行所需的时间太长。我之前使用“批量插入”来加快插入 10,000 行的速度,但我可以做些什么来加快更新部门的性能?

【问题讨论】:

您可能需要考虑获取所有行,在 php 中修改它们,然后删除并重新插入这些行。如果您采用这种方法,请务必进行备份... 嗯...与***.com/questions/60554294/…非常相似 @Nick 我考虑过,但客户说这是不行的。您是否知道任何其他可以加快流程的选项? 另一种选择可能是将新数据(与旧数据合并)写入另一个表,然后在旧表上使用多表更新查询 你和 tylerkmw 在同一个项目上工作吗? ***.com/questions/60554294/… 【参考方案1】:

更新记录中的 1 列或所有列基本上没有优势。开销在于记录、锁定和管理脏数据页——一个数据页通常包含多条记录。

如果我假设没有任何值被更新为 NULL,那么您可以创建一个更新表,其中包含:

正在更新的表的主键。 非NULL 列中的新值,其值正在发生变化。 NULL 未更改的列的值。

然后,更新看起来像:

update original o join
       updates u
       on o.pk = u.pk
    set o.col1 = coalesce(u.col1, o.col1),
        o.col2 = coalesce(u.col2, o.col2),
        . . . ;

不需要where 子句,因为updates 表中的每一行可能至少有一个非NULL 值。

【讨论】:

【参考方案2】:

Mysql 中的 10,000 行不算什么,特别是如果您在 where 子句中使用 PK(整数)。快速更新的秘诀是正确索引和使用 WHERE 子句。如果您需要更新所有行,那么您可能只需扫描整个表。

【讨论】:

以上是关于使用不同的列集更有效地更新大量行?的主要内容,如果未能解决你的问题,请参考以下文章

按组将不同的功能应用于不同的列集

如何通过读取、递增和更新数据库中的列来有效地保持计数

Google BigQuery SQL:使滚动平均子查询或加入对大型数据集更有效

比较pyspark中的列集

哪个 ORM 支持多行更新和删除

Spark DataSet 有效地获取整行的长度大小