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