10.5.3 InnoDB只读事务优化
InnoDB
可以避免为已知为只读的事务设置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.
您仍然可以在只读事务中对会话临时表进行更改,或者对它们发出锁定查询,因为这些更改和锁定对任何其他事务都是不可见的。
-
自动提交设置为开启状态,因此事务保证是一个单个语句,并且该语句是一个“非锁定”
SELECT
语句,即不使用FOR UPDATE
或LOCK IN SHARED MODE
子句的SELECT
语句。 -
事务开始时没有使用
READ ONLY
选项,但还未执行任何更新或明确锁定行的语句。直到需要更新或明确锁定行,事务将保持只读模式。
因此,对于一个读密集型应用程序,如报表生成器,您可以通过将START TRANSACTION READ ONLY
和COMMIT
语句组合它们,或者在运行SELECT
语句前将自动提交设置为开启状态,或者简单地避免在查询之间插入数据更改语句。
关于START TRANSACTION
和autocommit
的信息,请参阅第15.3.1节,“START TRANSACTION, COMMIT, and ROLLBACK Statements”.
自动提交、非锁定和只读事务(AC-NL-RO)将被排除在某些内部InnoDB
数据结构中,因此不在SHOW ENGINE INNODB STATUS
输出中。