InnoDB高并发写入性能优于MyISAM的根本原因是行级锁降低资源竞争粒度,但仅在WHERE条件命中索引、开启事务且隔离级别合理时生效;否则行锁退化为表锁,实际并发能力接近甚至低于MyISAM。

InnoDB在高并发写入下锁开销远低于MyISAM,但前提是WHERE条件能走索引;否则InnoDB也会锁全表,和MyISAM一样卡。
MyISAM一写就锁全表的典型表现
MyISAM没有行级锁概念,所有写操作(INSERT、UPDATE、DELETE)默认触发写优先的表级锁。只要一个线程开始写,整张表立刻不可读不可写。
-
SHOW PROCESSLIST里大量线程状态为Locked,这是最直接信号 - 哪怕只执行
UPDATE user SET status = 1 WHERE id = 123,其他SELECT COUNT(*)也会排队 -
REPAIR TABLE或OPTIMIZE TABLE过程中,表完全不可用 - 使用
DELAY_KEY_WRITE=1可缓解索引写压力,但断电即丢索引,线上基本不用
InnoDB行锁失效时会退化成全表锁
InnoDB的“行锁”本质是加在索引记录上的,不是物理行。一旦查询无法命中索引,就会扫描聚簇索引,锁住整个扫描范围——等效于锁表。
-
UPDATE user SET status = 1 WHERE name LIKE "%admin%":左模糊导致索引失效,InnoDB锁全表 -
UPDATE user SET status = 1 WHERE created_at > '2025-01-01':若created_at无索引,同样锁全表 - 非唯一索引 + 多行匹配 → 触发间隙锁(
GAP LOCK)或临键锁(NEXT-KEY LOCK),影响范围远超目标行 - 死锁发生后,
SHOW ENGINE INNODB STATUS才能看到真实阻塞链,SHOW PROCESSLIST只显示updating或waiting for table metadata lock
压测时怎么真实对比锁行为?
别只跑 SELECT,那会误判MyISAM“性能好”。必须模拟真实混合负载。
- 用
sysbench启动多线程,同时跑UPDATE+SELECT,观察Threads_running和平均延迟突增点 - 检查
information_schema.INNODB_TRX和INNODB_LOCK_WAITS,看事务是否长时间等待 - 对MyISAM表执行慢
INSERT ... SELECT,立刻观察其他连接是否全部卡在Locked - 对比
innodb_buffer_pool_size和key_buffer_size的实际作用对象:前者缓存InnoDB的数据页+索引页,后者只缓存MyISAM的索引文件(.MYI),对数据页无效
真正决定锁开销的从来不是引擎名字,而是索引设计+查询写法+并发模式。InnoDB给了你行锁的可能,但不会替你建索引;MyISAM省去了事务开销,代价是写操作永远单线程排队。线上环境几乎不存在“MyISAM更适合高并发写入”的场景——除非你把“高并发”定义为“零并发”。


















