### 8.5.3 Optimizing InnoDB Read-Only Transactions

`InnoDB` can avoid the overhead associated with setting up the [transaction ID](glossary.html#glos_transaction_id) (`TRX_ID` field) for transactions that are known to be read-only. A transaction ID is only needed for a [transaction](glossary.html#glos_transaction) that might perform write operations or [locking reads](glossary.html#glos_locking_read) such as `SELECT ... FOR UPDATE`. Eliminating unnecessary transaction IDs reduces the size of internal data structures that are consulted each time a query or data change statement constructs a [read view](glossary.html#glos_read_view).

`InnoDB` detects read-only transactions when:

* The transaction is started with the [`START TRANSACTION READ ONLY`](commit.html) statement. In this case, attempting to make changes to the database (for `InnoDB`, `MyISAM`, or other types of tables) causes an error, and the transaction continues in read-only state:

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

   You can still make changes to session-specific temporary tables in a read-only transaction, or issue locking queries for them, because those changes and locks are not visible to any other transaction.

* The [`autocommit`](server-system-variables.html#sysvar_autocommit) setting is turned on, so that the transaction is guaranteed to be a single statement, and the single statement making up the transaction is a “non-locking” [`SELECT`](select.html) statement. That is, a `SELECT` that does not use a `FOR UPDATE` or `LOCK IN SHARED MODE` clause.

* The transaction is started without the `READ ONLY` option, but no updates or statements that explicitly lock rows have been executed yet. Until updates or explicit locks are required, a transaction stays in read-only mode.

 Thus, for a read-intensive application such as a report generator, you can tune a sequence of `InnoDB` queries by grouping them inside [`START TRANSACTION READ ONLY`](commit.html) and [`COMMIT`](commit.html), or by turning on the [`autocommit`](server-system-variables.html#sysvar_autocommit) setting before running the `SELECT` statements, or simply by avoiding any data change statements interspersed with the queries.

 For information about [`START TRANSACTION`](commit.html) and [`autocommit`](server-system-variables.html#sysvar_autocommit), see [Section 13.3.1, “START TRANSACTION, COMMIT, and ROLLBACK Statements”](commit.html).

Note

 Transactions that qualify as auto-commit, non-locking, and read-only (AC-NL-RO) are kept out of certain internal `InnoDB` data structures and are therefore not listed in [`SHOW ENGINE INNODB STATUS`](show-engine.html) output.

