我正在努力使用INSERT .. ON DUPLICATE KEY UPDATE
来处理大型InnoDB表上的文件。
我的values
表保存属于客户端的每个实体的详细信息。实体只能拥有特定键的一个值。因此,当发生变化时,我们正在更新相同的内容。该表如下所示:
CREATE TABLE `key_values` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`client_id` int(11) NOT NULL COMMENT 'customer/tenant id',
`key_id` int(11) NOT NULL COMMENT 'reference to the keys',
`entity_id` bigint(20) NOT NULL,
`value` text,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `client_id` (`client_id`,`entity_id`,`key_id`),
KEY `client_id_2` (`client_id`,`key_id`)
) ;
所有写入查询的格式均为:
INSERT INTO `key_values`
(client_id, key_id, entity_id,value)
values
(23, 47, 147, 'myValue'), (...), (...)...
ON DUPLICATE KEY UPDATE value = values(value);
insert
目前,当有时(并非总是)发生离线活动时,我们会获得锁定等待超时。什么可以改变而不避免超时?
REPLACE
是另一个候选人,但我不想将生产中的删除权限赋予代码中的任何内容。INSERT IGNORE
然后UPDATE
是一个很好的候选人,但它会有很大改进吗?我还有其他选择吗?
提前感谢所有建议和答案。
答案 0 :(得分:2)
关于锁等待超时,可以通过mysql配置设置innodb_lock_wait_timeout进行更改,除了在my.cnf中更改它之外,可以动态修改(不重启mysql)。
关于锁等待,使用mysql要考虑的一件事是默认事务隔离级别,即REPEATABLE READ。此设置的副作用是,对于您可能期望的读取会发生更多锁定(特别是如果您具有SQL Server背景,其默认转换级别为READ COMMITTED)。现在,如果您不需要REPEATABLE READ,则可以使用SET TRANSACTION ISOLATION LEVEL语法在查询中更改您的tran iso级别,或者使用配置设置transaction-isolation更改整个服务器的tran iso级别。我建议使用READ COMMITTED,并考虑您的应用程序中是否还有其他地方甚至可以接受“更脏”的读取(在这种情况下,您可以使用READ UNCOMMITTED。