加快 UPDATE 性能 MySQL

Posted

技术标签:

【中文标题】加快 UPDATE 性能 MySQL【英文标题】:Speed Up UPDATE Performance MySQL 【发布时间】:2021-12-14 11:01:41 【问题描述】:

我对 SQL 还很陌生,因此在其他地方给出的指导上遇到了困难。

我有一个 170 万行 85 列的表格

“样品 ID”列为每个条目提供了一个标识符

数据会定期更新,并生成重复的样本 ID,并更改单独的字段(这是数据流的一部分)

但是,单位编号不会延续到样品 ID 上的新条目,因为这是根据更改的字段进行的计算的一部分

因此,我想使用填充它的样本 ID 中的单元号来填充它为 NULL 的地方

例如:

Sample ID Unit Number +83 other columns
00001A NULL
00001A 123_abc

Sample ID Unit Number +83 other columns
00001A 123_abc
00001A 123_abc

我已经成功地在一张小桌子上使用以下代码进行了测试:

UPDATE data_tabel as dt1, data_tabel as dt2 
SET dt1.Unit Number = dt2.Unit Number 
WHERE dt1.Sample ID = dt2.Sample ID AND dt1.Unit Number is NULL AND dt2.Unit Number != ''

也成功了:

UPDATE data_tabel as t1 
    INNER JOIN data_tabel as t2 ON 
        t1.Sample ID = t2.Sample ID AND 
        t2.Unit Number IS NOT NULL 
SET t1.Unit Number = t2.Unit Number;

但是,当在我的完整数据表上运行此程序时,速度非常慢(到目前为止 1.5 小时并且还在增加)。

任何关于如何提高性能的建议将不胜感激。

谢谢。

【问题讨论】:

更新集中有多少行?我正在考虑将其分开,然后将数据折叠起来——包括 UnitNumber。 PRIMARY KEY 是什么?请提供SHOW CREATE TABLE;您可以省略其他 83 列中的大部分,但要包括所有索引和被索引的列。 【参考方案1】:

DB 中UPDATEINSERT 过程中性能降低的主要因素是索引、触发器、约束和外键。为了获得最佳性能,您必须在UPDATEINSERT 期间禁用所有这些。例如:

SET FOREIGN_KEY_CHECKS = 0;
ALTER TABLE table_name disable KEYS;

-- update table_name
 
SET FOREIGN_KEY_CHECKS = 1;
ALTER TABLE table_name enable KEYS;

【讨论】:

【参考方案2】:

正如您在第二次尝试中所写的那样,希望只是您的代码粘贴错误,您正在更新每条记录,因为您没有

WHERE t1.UnitNumber IS NULL

有时试图屏蔽您的数据库和查询是不值得的,即使有些专有系统。一般的查询在剥离到基础知识时不应构成风险。此外,在列名(例如您的单位编号)中包含空格也很糟糕,但也认为这仅适用于您的屏蔽查询示例。

您可能需要查看您的数据...您想要什么。给定 SampleID 的第一个具有非空值的条目,还是要向下传递到所有其他条目的最新条目?您是否有此 SampleID 来自的主父表?如果是这样,也许这个最新的计算状态应该在该父记录上,而不是通过相同的上下文复制到每个详细信息行。

评估您的数据库设计实施可能比回补数据更好。

【讨论】:

以上是关于加快 UPDATE 性能 MySQL的主要内容,如果未能解决你的问题,请参考以下文章

MySQL UPDATE 性能...更快

MySQL降低insert, update, delete的优先级来优化性能

MySQL性能调优(软调优)

BEFORE 触发器和 ON UPDATE CURRENT_TIMESTAMP 之间的性能差异 - MySQL

数据库索引

使用文件排序的 MYSQL 性能变慢