我一直在环顾四周,阅读 mysql 站点,但仍然无法确切了解它是如何工作的。
我想选择并行锁定写入结果,写入更改并释放锁定。audocommit 已开启。
方案
id (int)
name (varchar50)
status (enum 'pending', 'working', 'complete')
created (datetime)
updated (datetime)
Run Code Online (Sandbox Code Playgroud)
选择状态为待处理的项目,并将其更新为工作状态。使用独占写入来确保同一项目不会被捡起两次。
所以;
"SELECT id FROM `items` WHERE `status`='pending' LIMIT 1 FOR WRITE"
Run Code Online (Sandbox Code Playgroud)
从结果中获取 id
"UPDATE `items` SET `status`='working', `updated`=NOW() WHERE `id`=<selected id>
Run Code Online (Sandbox Code Playgroud)
我是否需要做任何事情来释放锁,它是否像我上面所做的那样工作?
我有一个相当繁忙的 InnoDB 表(200,000 行,我猜大概每秒有几十个查询)。由于一个错误,我得到了 14 行(相同的)无效电子邮件地址,并想删除它们。
我只是尝试DELETE FROM table WHERE email='invalid address'并在大约 50 秒后得到“超出锁定等待超时”。这并不奇怪,因为行列没有编入索引。
但是,然后我做到了SELECT id FROM table WHERE email='invalid address',这花了 1.25 秒。运行DELETE FROM table WHERE id in (...),从 SELECT 结果中复制粘贴 id,花费了 0.02 秒。
到底是怎么回事?有人可以解释为什么带有条件的 DELETE 如此缓慢以至于超时,但是执行 SELECT 然后按 id 删除却如此之快?
谢谢。
编辑:根据要求,我发布了表结构以及一些explain结果。我还应该注意,没有引用此表的外键。
但是,情况对我来说似乎很简单:我选择了一个未编入索引的字段。这需要扫描整个表,但它并不是很大。id是主键,因此按 id 删除非常快,应该如此。
mysql> show create table ThreadNotification2 \G
*************************** 1. row ***************************
Table: ThreadNotification2
Create Table: CREATE TABLE `ThreadNotification2` (
`id` bigint(20) NOT …Run Code Online (Sandbox Code Playgroud)