MySQL事务本身不会直接拖慢查询速度,但隔离级别、长事务、显式加锁、高并发争抢、索引缺失等因素会显著降低查询性能;例如SELECT ... FOR UPDATE会触发行锁,长事务阻碍purge导致版本链膨胀,SERIALIZABLE使所有SELECT隐式加锁,无索引操作可能升级为表级锁。

MySQL事务本身不会直接拖慢查询速度,但它的存在会间接影响查询性能,关键在于事务的隔离级别、持续时间、锁机制以及并发访问模式。
事务开启后自动进入“可重复读”隔离级别
InnoDB默认隔离级别是REPEATABLE READ,它通过MVCC(多版本并发控制)实现快照读,对普通SELECT不加锁,性能影响较小。但以下情况会明显变慢:
- 显式加锁查询,如
SELECT ... FOR UPDATE或SELECT ... LOCK IN SHARE MODE,会触发行锁甚至间隙锁,阻塞其他事务 - 长事务中执行大量查询,会阻止purge线程清理undo日志,导致历史版本链膨胀,影响后续快照读效率
- 高并发下多个事务争抢同一行/索引范围时,锁等待时间上升,查询响应延迟增加
事务生命周期越长,资源占用越严重
一个未提交的事务会持续持有锁、占用undo空间、维持一致性视图。例如:
- 事务A开启后执行
UPDATE user SET status=1 WHERE id=100,但迟迟不提交;事务B随后执行SELECT ... FOR UPDATE WHERE id=100就会被阻塞 - 长时间运行的只读事务(如报表导出),也会让InnoDB保留旧版本数据,增大buffer pool压力和磁盘I/O
- 建议将事务控制在毫秒级完成,避免在事务内做网络调用、文件读写等耗时操作
高隔离级别带来额外开销
若将隔离级别提升到SERIALIZABLE,所有普通SELECT都会隐式加上共享锁,相当于给每条查询加了锁,极易引发锁冲突和等待。而READ COMMITTED虽然减少锁持有时间,但每次查询都生成新快照,频繁访问大表时可能加重undo扫描负担。
- 业务能接受“不可重复读”的,优先用
READ COMMITTED - 避免全局设置
SERIALIZABLE,仅对极少数强一致性场景按需使用 - 可通过
SELECT @@transaction_isolation确认当前会话级别
索引缺失放大事务负面影响
没有合适索引时,UPDATE/DELETE/SELECT FOR UPDATE可能升级为表级扫描+锁,导致锁住大量无关行。例如:
UPDATE order SET paid=1 WHERE create_time ,若create_time无索引,InnoDB需遍历全表并逐行加锁- 这种操作在事务中执行,不仅慢,还会让其他事务大面积阻塞
- 上线前务必检查WHERE条件字段是否已建立有效索引,并用
EXPLAIN验证执行计划











