我在使用特定的'in'谓词进行查询时,Mysql锁定整个表时出现了一个奇怪的问题。
这是有关的表格:
create table TableA (
USERID bigint(20) unsigned not null,
BLOBID tinyint unsigned not null,
blob_contents mediumblob not null,
primary key(ID1, ID2)) engine=innodb default charset=latin1;
有一个复合主键集(USERID,BLOBID)。以下是一些示例数据:
{[1, 1, <blob>],
[1, 2, <blob>],
[1, 3, <blob>],
[2, 1, <blob>],
[2, 2, <blob>]}
假设我想获取用户2的blobs 1,2和3的数据(此时我不知道该用户的id为3的blob没有行)。这是我要运行的查询:
select * from TableA where USERID = 2 and BLOBID in (1, 2, 3) for update;
查询为user2返回blob 1和2,并且没有为blobid 3找到任何内容。不幸的是,即使使用主键,此查询似乎也会锁定整个表。在解释查询时,您可以看到连接类型为“ALL”:
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | TABLEA | ALL | PRIMARY | NULL | NULL | NULL | 7 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
当我从in子句中删除'3'时,Mysql正确使用主键并仅锁定所需的2行:
select * from TableA where USERID = 2 and BLOBID in (1, 2) for update;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | TableA | range | PRIMARY | PRIMARY | 9 | NULL | 2 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
是否可以进行此查询,但只能锁定查询实际返回的行?