【问题标题】:Performance of VALUES(col_name) function in the UPDATE clauseUPDATE 子句中 VALUES(col_name) 函数的性能
【发布时间】:2016-06-03 08:24:46
【问题描述】:

问题是关于SQLMySQL 数据库的遗留代码。

众所周知,在执行 INSERT ... ON DUPLICATE KEY UPDATE 语句 VALUES(col_name) 函数 can be used 时,会引用来自 INSERT 部分的列值,而不是传递确切的值:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c)

我的遗留代码包含大量参数化样式的巨大插入(它们用于批量插入):

INSERT INTO table (a,b,c, <...dozens of params...>) VALUES (?,?,?,<...dozens of values...>)
  ON DUPLICATE KEY UPDATE b=?, c=?, <...dozens of params...>

问题是:如果我将所有这些查询更改为使用VALUES(col_name) 函数(在UPDATE 部分),它会提高批量插入的性能吗?

我的查询是使用 jdbc 驱动程序从 java 代码执行的。所以,我猜,对于长文本值,它应该显着减少查询的大小。 MySQL它自己呢?一般来说,它真的会让我提高速度吗?

【问题讨论】:

  • 是的,对于长值,您可能会获得边际收益,但这种努力几乎不值得,除非您每分钟插入大量记录
  • 我确实在几分钟内插入了很多记录
  • 猜猜这是值得的,因为更改不会占用您太多时间。

标签: mysql sql performance jdbc batch-insert


【解决方案1】:

批量插入的运行速度可以提高 10 倍,并且一次运行一行。原因是所有的网络等开销。

另一种技术是将单个批处理 IODKU 更改为两条语句——一条用于插入新行,一条用于更新。 (我不知道这是否会运行得更快。)Here 在“规范化”的背景下讨论了这两个步骤。

需要注意的另一件事:如果涉及AUTO_INCREMENT(不是提到的列之一),那么 IODKU 可能会在它执行“更新”的情况下“烧毁”ID。也就是说,IODKU(以及INSERT IGNORE 和其他一些人)获得了它可能需要的所有auto_inc,然后继续使用它确实需要的那些并浪费了其他人。

如果您尝试在一个批次中插入超过几百行,就会陷入“收益递减”。而你强调回滚日志。

【讨论】:

  • 您没有阅读问题:我已经在使用 BATCH instertion。问题是关于在更新部分使用VALUES 函数。
  • 真的吗?为什么是错的?我正在使用Spring JDBC 批量插入,所以在这种情况下语法是正确的
  • 在 MySQL 中,批量插入看起来像:INSERT INTO table (a,b,c) VALUES (1,2,3), (4,5,6), (11,22,33), ...。即 N 列名称,加上 M 组 N 值,将 M 行插入 N 列。你是说 Spring 有不同的语法吗?
  • 这是一个非常好的问题。它与我的问题没有直接关系,也没有回答,但应该单独阐述。
  • 好吧,我已经查看了 MySQL PreparedStatement 源,它具有将源 SQL 转换为批处理的特殊方法。所以,是的,Spring 在内部调用 mysql jdbc 驱动程序的 PrepatedStatement 的实现并使用这个正确的批处理语法。
猜你喜欢
  • 2020-05-23
  • 1970-01-01
  • 2021-08-28
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
相关资源
最近更新 更多