[英]Howto bulk update a InnoDB table without deadlocks?
我有两个表,一个具有多对多关系( fooBarTable
与列fooId
和barId
)和另一个InnoDB表fooCounterTable
与列fooId
和counter
计数fooId
中fooBarTable
。
当从fooBarTable
删除所有barId
,我需要相应地更新fooCounterTable
。
我尝试的第一件事是:
UPDATE fooCounterTable SET counter = counter - 1
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId);
但我得到了这个错误:
MySQL error (1205): Lock wait timeout exceeded; try restarting transaction
添加barId
时更新表可以正常使用此SQL语句:
INSERT INTO `fooCounterTable` (fooId, counter) VALUES (42,1), (100,1), (123,1)
ON DUPLICATE KEY UPDATE counter = counter + 1;
因此我认为在减少计数器时我会做同样的事情,即使插入0值看起来很愚蠢,这应该永远不会发生:
INSERT INTO `fooCounterTable` (SELECT fooId, 0 FROM fooBarTable WHERE barId = 42 ORDER BY fooId)
ON DUPLICATE KEY UPDATE counter = counter - 1;'
在大多数情况下,这似乎工作正常,但有时我会陷入僵局:
MySQL error (1213): Deadlock found when trying to get lock; try restarting transaction
所以我读到了关于死锁的信息并发现了有关SELECT ... FOR UPDATE
,我尝试了这个:
START TRANSACTION;
SELECT fooId FROM fooCounterTable
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId) FOR UPDATE;
UPDATE fooCounterTable SET counter = counter - 1
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId);
COMMIT;
结果导致:
MySQL error (2014): commands out of sync
谁能告诉我如何解决我的问题?
更新
最后一个错误(2014)发生了,因为在执行UPDATE语句之前我没有使用并释放SELECT语句的结果,这是必需的。 我解决了这个问题,我摆脱了2014年的错误,但我仍然不时遇到死锁(错误1205),我不明白,为什么。
你知道在解雇这个查询时你刚删除了什么fooID吗?
如果是这样似乎会起作用......
UPDATE fooCounterTable SET counter =
(SELECT count(*) FROM fooBarTable WHERE fooId = 42)
WHERE fooID = 42
我想知道你是否真的需要那个柜台。 如果您的索引设置正确,那么对于更规范化的方法,不应该有太多的速度惩罚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.