InnoDB
可以避免为只读事务设置事务 ID (TRX_ID
字段) 的开销。只有在可能执行写操作或锁定读取(如 SELECT ... FOR UPDATE
)时,事务 ID 才是必需的。消除不必要的事务 ID 可以减少内部数据结构的大小,这些结构在每次查询或数据更改语句构建读取视图时都会被咨询。
InnoDB
在以下情况下检测到只读事务:
-
事务以
START TRANSACTION READ ONLY
语句启动。在这种情况下,尝试对数据库进行更改(对于InnoDB
、MyISAM
或其他类型的表)将导致错误,并且事务将继续处于只读状态:ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction.
您仍然可以在只读事务中对会话特定的临时表进行更改,或者对其发出锁定查询,因为这些更改和锁定对其他事务不可见。
-
将
autocommit
设置打开,以便事务保证是一个单独的语句,并且该单独语句组成事务是一个非锁定SELECT
语句。也就是说,一个不使用FOR UPDATE
或LOCK IN SHARED MODE
子句的SELECT
。 -
事务没有使用
READ ONLY
选项启动,但尚未执行更新或明确锁定行的语句。直到更新或明确锁定被要求时,事务将保持只读模式。
因此,对于一个读取密集型应用程序,例如报告生成器,您可以通过将一系列 InnoDB
查询分组在 START TRANSACTION READ ONLY
和 COMMIT
之间,或者通过打开 autocommit
设置,然后运行 SELECT
语句,或者简单地避免在查询之间执行数据更改语句。
有关 START TRANSACTION
和 autocommit
的信息,请参阅 第 15.3.1 节,“START TRANSACTION, COMMIT, and ROLLBACK Statements”。
符合自动提交、非锁定和只读(AC-NL-RO)的事务将被排除在某些内部 InnoDB
数据结构之外,因此它们不会出现在 SHOW ENGINE INNODB STATUS
输出中。