mysql> explain select c from t where b in (3,5); +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | t | NULL | range | b | b | 5 | NULL | 2 | 100.00 | Using index condition | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
mysql> explain update t set c=1 where b in(3,5); +----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+-------------+ | 1 | UPDATE | t | NULL | range | b | b | 5 | const | 2 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+-------------+
当 b 的范围是 (3,5) 的时候,select 和 update 都使用了b 这个索引。
1 2 3 4 5 6 7 8 9 10 11 12 13
mysql> explain select c from t where b in (3,5,7); +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | t | NULL | ALL | b | NULL | NULL | NULL | 7 | 42.86 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
mysql> explain update t set c=1 where b in(3,5,7); +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | UPDATE | t | NULL | index | b | PRIMARY | 4 | NULL | 7 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
当 b 的范围是 (3,5,7) 的时候,select 没有使用索引,直接查表。update 使用了主键。
如果这里
1
update t set c=1where b in (3,5,7);
是一个事务,同时开另一个事务
1
update t set c=1where a=0;
这时第一个 sql 会锁表,第二个 sql 就会进入等待。注意这里还不是 gap lock 的情况。