我正在编写一个应用程序,它需要在很长一段时间内刷新对数据库的大量更新,但我一直在研究如何优化查询。目前我正在使用INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE,它可以将所有值批处理到一个查询中,但在大表上执行速度非常慢。我实际上不需要插入行。
我见过的其他方法是更新使用SET value = CASE WHEN...(由于我构建查询的方式,这将很难生成,而且我不确定CASE数百/数千个键的性能),并且只是多个连接更新。这些中的任何一个会比我目前的方法更快吗?
令我困惑的是,据我所知,在 MySQL 中没有惯用的、有效的方法来做到这一点。如果真的没有比 更快的方法,ON DUPLICATE KEY那么切换到 PostgreSQL 并使用其UPDATE FROM语法是否值得?
任何其他建议也非常感谢!
编辑:这是经常更新的表之一。我删除了列名,因为它们不相关。
CREATE TABLE IF NOT EXISTS `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`a` bigint(20) unsigned NOT NULL DEFAULT '0',
`b` bigint(20) unsigned NOT NULL DEFAULT '0',
`c` enum('0','1','2') NOT NULL DEFAULT '0',
`d` char(32) NOT NULL,
-- trimmed --
PRIMARY KEY (`id`),
KEY `a` (`a`),
KEY `b` (`b`),
KEY `c` (`c`),
KEY `d` (`d`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
Shl*_*ach 17
由于您使用的是InnoDB表,最明显的优化是将多个UPDATEs分组到一个事务中。
有了InnoDB,是一个交易引擎,你付出不只是为UPDATE自己,也为所有的事务开销:管理到交易缓存,事务日志刷新日志到磁盘。
如果您在逻辑上对这个想法感到满意,请尝试UPDATE一次将100-1000 s分组,每次都这样包装:
START TRANSACTION;
UPDATE ...
UPDATE ...
UPDATE ...
UPDATE ...
COMMIT;
Run Code Online (Sandbox Code Playgroud)
可能的缺点:
UPDATE秒,因此您可能还需要一些超时时间| 归档时间: |
|
| 查看次数: |
36720 次 |
| 最近记录: |