一、基于主键 / 索引的 UPDATE (不会阻塞的情况)
当 UPDATE 条件用主键 / 索引字段(比如 id 是主键)时:
- 第一条
UPDATE id < 10:数据库会精准锁定(-∞, 10)范围的索引 / 数据,其他范围不受影响。 - 第二条
UPDATE id > 15:锁定(15, +∞)范围 。
由于锁定的索引范围不重叠,两条语句互不干扰,不会阻塞。
本质是 索引锁(Record Lock、Gap Lock 等)的 “范围隔离” 特性,让不重叠的范围更新可并行。
二、非主键 / 索引字段的 UPDATE (会阻塞的情况)
若 UPDATE 条件用非索引字段(比如用 name 但 name 没建索引):
-
数据库无法走索引,只能全表扫描找符合条件的行。
-
全表扫描时,会对所有行加 “行级锁” (或因扫描逻辑触发间隙锁等),相当于把整个表 “锁住” 。
-
此时,第一条
UPDATE执行时会占住锁,第二条UPDATE要等锁释放才执行,就会阻塞。
核心是 无索引导致全表扫描,触发全局锁竞争,破坏并行性。
简单总结:
- 走索引(主键 / 索引字段) → 锁范围精准不冲突 → 不阻塞;
- 不走索引(非索引字段) → 全表扫描 + 全局锁 → 阻塞 。
本质是 索引对锁范围的 “精准控制” vs 无索引时的 “全局锁竞争” 的区别~