Mysql 将使用范围谓词“UPDATE语句”;“更喜欢”;非锁定行
给定一个名为Mysql 将使用范围谓词“UPDATE语句”;“更喜欢”;非锁定行,mysql,sql-update,mysql-5.7,Mysql,Sql Update,Mysql 5.7,给定一个名为workers的表和一个包含列leaderId,lastUpdated的架构。当多个DB连接运行此UPDATE语句时,是否会首先考虑更新满足谓词(WHERE子句)的未锁定行,还是将查询块放在已锁定的匹配行上?如果不首先考虑解锁,有没有办法做到这一点 BEGIN UPDATE workers SET leaderId = ?, lastUpdated = NOW(6) WHERE lastUpdated IS NULL OR lastUpdated < DATE_SUB(NOW
workers
的表和一个包含列leaderId
,lastUpdated
的架构。当多个DB连接运行此UPDATE
语句时,是否会首先考虑更新满足谓词(WHERE
子句)的未锁定行,还是将查询块放在已锁定的匹配行上?如果不首先考虑解锁,有没有办法做到这一点
BEGIN
UPDATE workers SET leaderId = ?, lastUpdated = NOW(6)
WHERE lastUpdated IS NULL OR lastUpdated < DATE_SUB(NOW(6),INTERVAL 3 SECOND)
LIMIT 1;
SELECT * FROM workers WHERE leaderId = ?;
COMMIT
开始
更新工人集leaderId=?,lastUpdated=NOW(6)
其中lastUpdated为NULL或lastUpdated
简短回答:否
长答覆:
要么全部,要么一个也没有。这是InnoDB“交易”的首要任务。您的BEGIN
…COMMIT
控制事务的范围
DATE\u SUB(现在(6),间隔3秒)
和NOW(6)
将在UPDATE
语句的开头计算一次
您有限制1
,但没有订购人
。这意味着您无法预测将拾取哪一行。但是,优化器不会根据执行查询的速度以外的任何其他因素来选择行,而不考虑可能锁定的内容
看起来您正在实现一个“队列”?UPDATE
“抓取”一行,然后SELECT
获取该行中的数据
或
优化效果不佳。一般来说,没有索引是有用的,因此UPDATE
将以某种方便的顺序扫描整个表,在发现满足一个或另一个条件时停止
或
通常的优化是将其分为两个查询。这可能意味着更改总体逻辑,使主代码获取一个NULL
。还有一个单独的“收割机”流程,围绕着抓取任何“旧”物品(可能是由于工人崩溃而成为孤儿)运行
(我不太愿意建议重写,因为我不完全理解您的逻辑。我希望表队列将被执行,而不是工作者。因此,请解释您的代码。我可能有其他提示。)mysql8.0的选择…进行更新语法的一部分。但是,它在MySQL-5.7中不可用