InnoDB可以避免为只读事务设置事务ID(TRX_ID字段)带来的开销,事务ID仅仅被需要于可能执行写入操作或者锁定读取(select ... for update)的事务。消除不必要的事务ID可以减少在每次查询或数据更改语句构造读取视图时需要查询的内部数据结构的大小。
InnoDB 在以下情况下检测只读事务:
- 由start transaction with read only的语句启动的事务。在这种情况下,尝试修改数据库(InnoDB,MyISAM或其他类型的表)会导致一个错误,事务会继续处于只读状态:
ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction.
- autocommit设置是打开的,所以事务内保证是单个语句,并且这个语句是一个非锁定的select语句。也就是说:一个没有使用for update 或LOCK in SHARED MODE 的select语句。
- 解释:autocommit 设置打开并且 select 语句没有用 for update 或者
LOCK IN SHARED MODE
- 解释:autocommit 设置打开并且 select 语句没有用 for update 或者
- 事务启动时没有READ ONLY 参数(START TRANSACTION),但是还没有执行显示锁定行或者更新语句。在需要更新或者显示锁之前,事务保持只读模式。
因此,对于读取密集型应用,比如报表生成器,你可以调优一系列的innoDB查询,通过将这些语句分组在 START TRANSACTION READ ONLY 和 COMMIT之间,或者在运行select语句之前将autocommit设置打开,或者简单的避免在查询中混合任何数据更改语句。