### 8.5.3 优化 InnoDB 只读事务

`InnoDB`可以避免与设置相关的开销[交易编号](glossary.html#glos_transaction_id)(`TRX_ID`字段）用于已知为只读的事务。交易 ID 仅用于[交易](glossary.html#glos_transaction)可能执行写操作或[锁定读取](glossary.html#glos_locking_read)如`选择 ... 更新`.消除不必要的事务 ID 可以减少每次查询或数据更改语句构造一个[阅读视图](glossary.html#glos_read_view).

`InnoDB`在以下情况下检测只读事务：

-   交易开始于[`开始交易 只读`](commit.html)陈述。在这种情况下，尝试对数据库进行更改（例如`InnoDB`,`MyISAM`，或其他类型的表）会导致错误，并且事务继续以只读状态：

    ```
    ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction.
    ```

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

-   这[`自动提交`](server-system-variables.html#sysvar_autocommit)设置开启，这样保证事务是单条语句，构成事务的单条语句是“非锁定”的[`选择`](select.html)陈述。这是一个`选择`不使用`更新`要么`锁定共享模式`条款。

-   交易开始时没有`只读`选项，但尚未执行显式锁定行的更新或语句。在需要更新或显式锁定之前，事务一直处于只读模式。

    因此，对于诸如报告生成器之类的阅读密集型应用程序，您可以调整一系列`InnoDB`通过在里面分组查询[`开始交易 只读`](commit.html)和[`犯罪`](commit.html)，或通过打开[`自动提交`](server-system-variables.html#sysvar_autocommit)运行前设置`选择`语句，或者简单地避免在查询中穿插任何数据更改语句。

    有关信息[`开始交易`](commit.html)和[`自动提交`](server-system-variables.html#sysvar_autocommit)， 看[第 13.3.1 节，“START TRANSACTION、COMMIT 和 ROLLBACK 语句”](commit.html).

笔记

符合自动提交、非锁定和只读 (AC-NL-RO) 条件的事务被排除在某些内部`InnoDB`数据结构，因此未在[`显示引擎 INNODB 状态`](show-engine.html)输出。
