创建两个表以进行比较:

create table t1(id integer primary key);
create table t2(id integer primary key, num integer);
insert into t1 values (0),(3),(6),(9);
insert into t2 values (0, 0), (3, 3), (6, 6), (9, 9);

启动事务tx1并对表t1执行锁定读取:

start transaction;
select * from t1 where id >=3 and id < 8 for update;

tx1持有的锁如下所示:

enter image description here

现在回滚tx1,启动事务tx2并对表t2执行锁定读取:

start transaction;
select * from t2 where id >=3 and id < 8 for update;

tx2持有的锁如下所示:

enter image description here

tx2的行为符合我对MySQL锁定模型的理解.为什么tx1锁定表t1中的每条索引记录?

="=引用=外部链接=

现在使用解释,我看到了一些不同之处:

enter image description here

推荐答案

已判断的所有行都被锁定.

答案就在解释报告中.执行type: index的查询正在执行索引扫描,它判断索引的每个成员.在主索引的情况下,这可以有效地判断整个表.

执行type: range的查询正在判断行的子集.

优化器出于某种原因 Select 执行索引扫描.我不确定具体原因.这可能取决于您使用的MySQL版本.您可以使用以下查询进行判断:SELECT VERSION();


我认为,当此查询是覆盖索引时,它将被视为索引扫描.这就是解释说明,上面写着"使用索引".如果查询提取的列与索引中的列相同,则它是覆盖索引.

如果测试以下查询,则会得到相同的优化策略(索引扫描):

select id from t2 where id >=3 and id < 8 for update;

因为id是主键索引的列,也是查询返回的唯一列.

Mysql相关问答推荐

如何使RST(*)在巨大的数据集上快速执行?

表列中的SQL SUM MENY值记录单个查询

发生的原因及解决方法

如何在 Shopware 6 DAL 中实施 Haversine 公式?

当mysql中只有一个索引列时,为什么使用范围条件锁定读取会锁定每条记录?

有没有比使用 MySQL 计划事件更好的方法来更新我的数据库表中的列?

MySQL DISTINCT 日期仅返回特定表的 1 个值.相同的查询适用于其他表

按 SQL 删除分组前的重复项

Laravel 查询构建器 where() 用于何时产品必须有多个标签(使用 product_tags 数据透视表多对多)

从 2 个不同的表中获取数据并将它们加入 sql

Mysql 相等性反对 false 或 true

MySQL 查询组按日期(12 小时间隔)

如何通过未知列中的唯一值有效地更新 MySQL 行

为什么在有 BEGIN 和 END 时为存储过程指定分隔符?

Facebook user_id:big_int、int 还是 string?

MySQL:如何多次加入同一张表?

Laravel classloader.php 错误打开流失败:没有这样的文件或目录

MySQL解释计划中 Select 优化的表的含义

将 MySQL 数据库置于版本控制之下?

将mysql查询输出存储到shell变量中