【问题标题】:Improving Speed of SQL 'Update' function - break into Insert/ Delete?提高 SQL“更新”功能的速度 - 插入/删除?
【发布时间】:2015-04-30 19:08:40
【问题描述】:

我正在运行 ETL 进程并将数据流式传输到 MySQL 表中。

现在它是通过网络连接编写的(相当快的)——所以这可能是一个瓶颈。

无论如何,这是一个基本的插入/更新功能。它是一个作为主键/索引的 ID 列表......然后是一些属性。

如果找到新 ID,则插入,否则,更新……你明白了。

目前基于 ID(索引)执行“更新,否则插入”功能需要 13 行/秒(这看起来很糟糕,对吧?)。这是将 1000 行与 250k 记录的数据库进行比较,以获取上下文。

当做一个“纯”插入所有方法时,为了比较,已经将过程加速到 26 行/秒。

纯“插入”方法的问题是我可以一次“插入”20 个并行连接......(网络主机允许最多 20 个)......而任何“更新”功能都不能有任何并行正在运行。

因此 26 x 20 = 520 转/秒。远远大于 13 r/s,尤其是如果我可以安装一些东西,允许更多数据并行推送。

我的问题是......鉴于插入与更新的巨大好处,有没有办法复制“更新”功能(我只希望给定 ID 的最新插入能够存活)......通过进行大量插入,然后在事后运行删除函数,删除不是“最新”的重复 ID?

这是容易实现的东西,还是经常出现的东西?

我还能做些什么来确保这个更新过程更快?我知道摆脱 ETL 工具和 DB 之间的“网络连接”是一个开始,但还有什么?这似乎是一个相当普遍的问题。

最终有 20 列,最大可能是 varchar(50) ...我应该得到比 13 行多得多的处理/秒吗?

【问题讨论】:

  • 您的“更新,否则插入”代码目前是什么样的?

标签: mysql database performance optimization insert-update


【解决方案1】:

您的问题有很多可能的“答案”。

13/秒 -- 可以做很多事情......

INSERT ... ON DUPLICATE KEY UPDATE ... ('IODKU') 通常是执行“更新,否则插入”的最佳方式(除非我不知道您的意思)。

批量插入比一次插入一行要快得多。最佳值约为 100 行,可提供 10 倍的加速。 IODKU(通常)也可以批量处理;参见VALUES() 伪函数。

BEGIN;...大量写入...COMMIT; 显着减少了事务开销。

使用“暂存”表来收集更新信息可以带来显着的好处。 My blog discussing that. 这也包括批量“标准化”。

动态构建汇总表会干扰高速数据摄取。 Another blog covers Summary tables.

标准化可用于重复数据删除,从而缩小磁盘占用空间。这对于减少数据仓库中“事实”表的 I/O 可能很重要。 (我指的是你的 20 x VARCHAR(50)。)

RAID 条带化是一种硬件帮助。

RAID 控制器上的 Batter-Backed-Write-Cache 使写入看起来是即时的。

SSD 加快了 I/O。

如果您提供一些更具体的信息(SHOW CREATE TABLE、SQL 等),我可以更具体。

【讨论】:

    【解决方案2】:

    在 DBMS 中执行,并将其包装在事务中。

    解释一下:

    1. 以尽可能最快的方式将数据加载到 MySQL 中的临时表中。批量加载,插入,做任何工作。查看“加载数据文件”。

    2. 将临时表外连接到目标表,插入目标表PK列为NULL的行。

    3. 将临时表外连接到目标表,并更新目标表的PK列不为NULL的那些行。

    将第 2 步和第 3 步包装在 begin/commit(或 [start transaction]/commit 对的事务中。默认行为可能是自动提交,这意味着您在每次插入/更新后都会执行大量数据库工作. 正确使用交易,每个区块只做一次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-12
      • 2016-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      相关资源
      最近更新 更多