对于使用主键进行范围查询的情况
CREATE TABLE hero (
number INT,
name VARCHAR(100),
country varchar(100),
PRIMARY KEY (number),
KEY idx_name (name)
) Engine=InnoDB CHARSET=utf8;
SELECT * FROM hero WHERE number <= 8 LOCK IN SHARE MODE; 和SELECT * FROM hero WHERE number <= 8 FOR UPDATE
- 1.先到聚簇索引中定位到满足number <= 8的
第一条
记录,为其加锁 - 2.判断一下该记录是否符合索引条件下推中的条件--只有非主键索引才可以条件下推
- 3.判断一下该记录是否符合范围查询的边界条件,符合的话返回server层,不符合则释放锁
- 4.将该记录返回到server层继续判断--server主要是判断记录是否满足wehere条件
凡是没有经过索引条件下推的条件都需要放到server层再判断一遍。 - 5.然后顺着该记录的链表进行范围查找,找寻到的每一个记录都按照1到4的步骤,一直
找到一条记录不符合为止,这个不符合的记录也会先加锁后被释放。
UPDATE hero SET country = '汉' WHERE number >= 8和DELETE FROM hero WHERE number = 8
- 1.该语句的实际执行步骤是首先更新对应的number值为8的聚簇索引记录,再更新对应的二级索引记录,所以加锁的步骤就是:
- 2.首先为number值为8的聚簇索引记录加上X型正经记录锁(该记录对应的)。
- 3.为该聚簇索引记录对应的idx_name二级索引记录(也就是name值为'c曹操',number值为8的那条二级索引记录)加上X型正经记录锁。
SELECT * FROM hero WHERE name = 'c曹操' LOCK IN SHARE MODE;
- 1.这个语句的执行过程是先通过二级索引idx_name定位到满足name = 'c曹操'条件的二级索引记录,然后进行回表操作
- 2.所以先要对二级索引记录加S型正经记录锁,然后再给对应的聚簇索引记录加S型正经记录锁.
SELECT * FROM hero FORCE INDEX(idx_name) WHERE name >= 'c曹操' LOCK IN SHARE MODE;
- 1.FORCE INDEX(idx_name)可以强制走索引
- 2.先对一条记录加了锁,然后再判断该记录是不是符合索引条件下推的条件,如果不符合直接跳到下一条记录或者直接向server层报告查询完毕,这个过程中并没有把那条被加锁的记录上的锁释放掉呀
网友评论