MySQL中表锁、行锁和页锁哪种锁粒度在并发环境下对性能影响最大?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1242个文字,预计阅读时间需要5分钟。
MySQL的MyISAM引擎仅支持表级锁,执行INSERT、UPDATE、DELETE时,会锁定整个表。这意味着同时进行的两个事务修改的是不同行的数据,也会相互等待。典型表现是使用SHOW PROCESSLIST查看时,会看到大量LOCKED状态的线程。
但它在全表扫描类操作(如 ALTER TABLE、OPTIMIZE TABLE)或一次性导入百万级数据时反而更高效:没有行锁开销,也无需维护锁队列。如果你的应用以读多写少、且写操作集中在离线任务中(比如凌晨 ETL),MyISAM 表锁未必是瓶颈。
常见误用点:
- 在高并发 OLTP 场景下误选
MyISAM,导致写请求排队雪崩 - 没意识到
SELECT ... FOR UPDATE在MyISAM下不生效(它根本不支持事务和行锁) - 用
LOCK TABLES t1 WRITE手动加锁后忘记UNLOCK TABLES,造成后续所有操作挂起
InnoDB 默认行锁,但容易因索引失效退化为表锁
InnoDB 的行锁实际是“索引记录锁”,只对满足条件且命中索引的行加锁。一旦 WHERE 条件无法使用索引(比如对无索引字段查询、或用了函数如 WHERE YEAR(create_time) = 2024),InnoDB 就会升级为全表扫描+全表加锁——效果等同于表锁。
本文共计1242个文字,预计阅读时间需要5分钟。
MySQL的MyISAM引擎仅支持表级锁,执行INSERT、UPDATE、DELETE时,会锁定整个表。这意味着同时进行的两个事务修改的是不同行的数据,也会相互等待。典型表现是使用SHOW PROCESSLIST查看时,会看到大量LOCKED状态的线程。
但它在全表扫描类操作(如 ALTER TABLE、OPTIMIZE TABLE)或一次性导入百万级数据时反而更高效:没有行锁开销,也无需维护锁队列。如果你的应用以读多写少、且写操作集中在离线任务中(比如凌晨 ETL),MyISAM 表锁未必是瓶颈。
常见误用点:
- 在高并发 OLTP 场景下误选
MyISAM,导致写请求排队雪崩 - 没意识到
SELECT ... FOR UPDATE在MyISAM下不生效(它根本不支持事务和行锁) - 用
LOCK TABLES t1 WRITE手动加锁后忘记UNLOCK TABLES,造成后续所有操作挂起
InnoDB 默认行锁,但容易因索引失效退化为表锁
InnoDB 的行锁实际是“索引记录锁”,只对满足条件且命中索引的行加锁。一旦 WHERE 条件无法使用索引(比如对无索引字段查询、或用了函数如 WHERE YEAR(create_time) = 2024),InnoDB 就会升级为全表扫描+全表加锁——效果等同于表锁。

