我需要SELECT FOR UPDATE
(resp. LOCK IN SHARE MODE
)的帮助。
我有一个包含大约400,000条记录的表格,我需要在每一行上运行两个不同的处理函数。
表结构恰如其分:
data (
`id`,
`mtime`, -- When was data1 set last
`data1`,
`data2` DEFAULT NULL,
`priority1`,
`priority2`,
PRIMARY KEY `id`,
INDEX (`mtime`),
FOREIGN KEY ON `data2`
)
功能略有不同:
priority1
选择记录;设置data1
和mtime
priority2
选择记录;设置data1
和mtime
他们不应该同时修改同一行,但是select可能会返回两行中的一行(priority1
和priority2
具有不同的值)并且事务可以等待如果是这种情况(我希望这将是它阻止的唯一情况)。
我正在根据以下查询选择数据:
-- For the first function - not processed first, then the oldest,
-- the same age goes based on priority
SELECT id FROM data ORDER BY mtime IS NULL DESC, mtime, priority1 LIMIT 250 FOR UPDATE;
-- For the second function - only processed not processed order by priority
SELECT if FROM data ORDER BY priority2 WHERE data2 IS NULL LIMIT 50 FOR UPDATE;
但我遇到的是每次只有一次查询返回。
所以我的问题是:
SELECT ... FROM (SELECT ...) WHERE ... IN (SELECT)
的提示都会受到赞赏)?ORDER BY ... LIMIT ...
会导致任何问题吗?答案 0 :(得分:3)
在深入了解之前要检查的关键事项:
根据我的判断,订单和限制对您遇到的问题没有任何影响,Select将返回的是将被锁定的行。
回答你的问题:
答案 1 :(得分:0)
接受答案中的所有分数似乎都不错,但低于2分: " Select将返回的内容将是被锁定的行。" &安培; " 索引和密钥是否会导致任何问题? 但他们不应该因为获得锁定而导致任何问题。"
而是在决定选择和返回哪些行时,DB内部读取的所有行都将被锁定。例如,下面的查询将锁定表的所有行,但可能只选择并返回几行: select * from table from non_primary_non_indexed_column =?更新 由于没有索引,因此DB必须读取整个表以搜索所需的行,从而锁定整个表。
如果只想锁定一行,则需要在where子句中指定其主键或索引列。因此,在仅锁定适当的行的情况下,索引变得非常重要。
这是一个很好的参考 - https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html