8.5.3 优化 InnoDB 只读事务

InnoDB可以避免与为已知为只读的事务设置transaction ID(TRX_ID字段)相关的开销。只有可能执行写操作的transactionlocking readsSELECT ... FOR UPDATE才需要事务 ID。消除不必要的事务 ID 可以减少每次查询或数据更改语句构造read view时都要查询的内部数据结构的大小。

InnoDB在以下情况下检测到只读事务:

  • Transaction 以仅开始 Transaction语句开始。在这种情况下,尝试对数据库(针对InnoDBMyISAM或其他类型的 table)进行更改会导致错误,并且事务将 continue 以只读状态运行:
ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction.

您仍然可以在只读事务中对特定于会话的临时 table 进行更改,或对其发出锁定查询,因为这些更改和锁对其他任何事务都不可见。

  • autocommit设置已打开,因此保证事务是单个语句,组成事务的单个语句是“非锁定” SELECT语句。也就是说,不使用FOR UPDATELOCK IN SHARED MODE子句的SELECT

  • 没有READ ONLY选项的情况下开始事务,但是尚未执行任何显式锁定行的更新或语句。在需要更新或显式锁之前,事务将保持只读模式。

因此,对于诸如报 table 生成器之类的读取密集型应用程序,您可以通过将InnoDB查询序列分组在仅开始 TransactionCOMMIT内,或者通过在运行SELECT语句之前打开autocommit设置,或简单地避免任何数据更改来调整InnoDB查询序列语句散布在查询中。

有关START TRANSACTIONautocommit的信息,请参见第 13.3.1 节“ START TRANSACTION,COMMIT 和 ROLLBACK 语句”

Note

符合自动提交,非锁定和只读(AC-NL-RO)资格的事务被排除在某些内部InnoDB数据结构之外,因此未在显示引擎的 INNODB 状态输出中列出。