### 8.9.3 Optimizer Hints

[]()[]()

 One means of control over optimizer strategies is to set the [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) system variable (see [Section 8.9.2, “Switchable Optimizations”](switchable-optimizations.html)). Changes to this variable affect execution of all subsequent queries; to affect one query differently from another, it is necessary to change [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) before each one.

 Another way to control the optimizer is by using optimizer hints, which can be specified within individual statements. Because optimizer hints apply on a per-statement basis, they provide finer control over statement execution plans than can be achieved using [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch). For example, you can enable an optimization for one table in a statement and disable the optimization for a different table. Hints within a statement take precedence over [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) flags.

 Examples:

```
SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1
  FROM t3 WHERE f1 > 30 AND f1 < 33;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
SELECT /*+ NO_ICP(t1, t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
SELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
EXPLAIN SELECT /*+ NO_ICP(t1) */ * FROM t1 WHERE ...;
SELECT /*+ MERGE(dt) */ * FROM (SELECT * FROM t1) AS dt;
INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2);
```

 Optimizer hints, described here, differ from index hints, described in [Section 8.9.4, “Index Hints”](index-hints.html). Optimizer and index hints may be used separately or together.

* [Optimizer Hint Overview](optimizer-hints.html#optimizer-hints-overview)

* [Optimizer Hint Syntax](optimizer-hints.html#optimizer-hints-syntax)

* [Join-Order Optimizer Hints](optimizer-hints.html#optimizer-hints-join-order)

* [Table-Level Optimizer Hints](optimizer-hints.html#optimizer-hints-table-level)

* [Index-Level Optimizer Hints](optimizer-hints.html#optimizer-hints-index-level)

* [Subquery Optimizer Hints](optimizer-hints.html#optimizer-hints-subquery)

* [Statement Execution Time Optimizer Hints](optimizer-hints.html#optimizer-hints-execution-time)

* [Variable-Setting Hint Syntax](optimizer-hints.html#optimizer-hints-set-var)

* [Resource Group Hint Syntax](optimizer-hints.html#optimizer-hints-resource-group)

* [Optimizer Hints for Naming Query Blocks](optimizer-hints.html#optimizer-hints-query-block-naming)

#### Optimizer Hint Overview

 Optimizer hints apply at different scope levels:

* Global: The hint affects the entire statement

* Query block: The hint affects a particular query block within a statement

* Table-level: The hint affects a particular table within a query block

* Index-level: The hint affects a particular index within a table

 The following table summarizes the available optimizer hints, the optimizer strategies they affect, and the scope or scopes at which they apply. More details are given later.

[]()

**Table 8.2 Optimizer Hints Available**

|                                                                              Hint Name                                                                              |                                                                                                                                                                                                                                                Description                                                                                                                                                                                                                                                |Applicable Scopes |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|
|                       [`BKA`](optimizer-hints.html#optimizer-hints-table-level), [`NO_BKA`](optimizer-hints.html#optimizer-hints-table-level)                       |                                                                                                                                                                                                                                Affects Batched Key Access join processing                                                                                                                                                                                                                                 |Query block, table|
|                       [`BNL`](optimizer-hints.html#optimizer-hints-table-level), [`NO_BNL`](optimizer-hints.html#optimizer-hints-table-level)                       |                                                                                                                                                        Prior to MySQL 8.0.20: affects Block Nested-Loop join processing; MySQL 8.0.18 and later: also affects hash join optimization; MySQL 8.0.20 and later: affects hash join optimization only                                                                                                                                                         |Query block, table|
|[`DERIVED_CONDITION_PUSHDOWN`](optimizer-hints.html#optimizer-hints-table-level), [`NO_DERIVED_CONDITION_PUSHDOWN`](optimizer-hints.html#optimizer-hints-table-level)|                                                                                                                                                                                             Use or ignore the derived condition pushdown optimization for materialized derived tables (Added in MySQL 8.0.22)                                                                                                                                                                                             |Query block, table|
|               [`GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level)               |                                                                                                                                                                                               Use or ignore the specified index or indexes for index scans in `GROUP BY` operations (Added in MySQL 8.0.20)                                                                                                                                                                                               |      Index       |
|                 [`HASH_JOIN`](optimizer-hints.html#optimizer-hints-table-level), [`NO_HASH_JOIN`](optimizer-hints.html#optimizer-hints-table-level)                 |                                                                                                                                                                                                                             Affects Hash Join optimization (MySQL 8.0.18 only                                                                                                                                                                                                                             |Query block, table|
|                     [`INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_INDEX`](optimizer-hints.html#optimizer-hints-index-level)                     |Acts as the combination of [`JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level), and [`ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level), or as the combination of [`NO_JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level), and [`NO_ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level) (Added in MySQL 8.0.20)|      Index       |
|               [`INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level), [`NO_INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level)               |                                                                                                                                                                                                                                     Affects Index Merge optimization                                                                                                                                                                                                                                      |   Table, index   |
|                                                [`JOIN_FIXED_ORDER`](optimizer-hints.html#optimizer-hints-join-order)                                                |                                                                                                                                                                                                                         Use table order specified in `FROM` clause for join order                                                                                                                                                                                                                         |   Query block    |
|                [`JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level)                |                                                                                                                                                                                                        Use or ignore the specified index or indexes for any access method (Added in MySQL 8.0.20)                                                                                                                                                                                                         |      Index       |
|                                                   [`JOIN_ORDER`](optimizer-hints.html#optimizer-hints-join-order)                                                   |                                                                                                                                                                                                                             Use table order specified in hint for join order                                                                                                                                                                                                                              |   Query block    |
|                                                  [`JOIN_PREFIX`](optimizer-hints.html#optimizer-hints-join-order)                                                   |                                                                                                                                                                                                                     Use table order specified in hint for first tables of join order                                                                                                                                                                                                                      |   Query block    |
|                                                  [`JOIN_SUFFIX`](optimizer-hints.html#optimizer-hints-join-order)                                                   |                                                                                                                                                                                                                      Use table order specified in hint for last tables of join order                                                                                                                                                                                                                      |   Query block    |
|                                             [`MAX_EXECUTION_TIME`](optimizer-hints.html#optimizer-hints-execution-time)                                             |                                                                                                                                                                                                                                      Limits statement execution time                                                                                                                                                                                                                                      |      Global      |
|                     [`MERGE`](optimizer-hints.html#optimizer-hints-table-level), [`NO_MERGE`](optimizer-hints.html#optimizer-hints-table-level)                     |                                                                                                                                                                                                                         Affects derived table/view merging into outer query block                                                                                                                                                                                                                         |      Table       |
|                       [`MRR`](optimizer-hints.html#optimizer-hints-index-level), [`NO_MRR`](optimizer-hints.html#optimizer-hints-index-level)                       |                                                                                                                                                                                                                                   Affects Multi-Range Read optimization                                                                                                                                                                                                                                   |   Table, index   |
|                                                    [`NO_ICP`](optimizer-hints.html#optimizer-hints-index-level)                                                     |                                                                                                                                                                                                                               Affects Index Condition Pushdown optimization                                                                                                                                                                                                                               |   Table, index   |
|                                             [`NO_RANGE_OPTIMIZATION`](optimizer-hints.html#optimizer-hints-index-level)                                             |                                                                                                                                                                                                                                        Affects range optimization                                                                                                                                                                                                                                         |   Table, index   |
|               [`ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level)               |                                                                                                                                                                                                           Use or ignore the specified index or indexes for sorting rows (Added in MySQL 8.0.20)                                                                                                                                                                                                           |      Index       |
|                                                [`QB_NAME`](optimizer-hints.html#optimizer-hints-query-block-naming)                                                 |                                                                                                                                                                                                                                        Assigns name to query block                                                                                                                                                                                                                                        |   Query block    |
|                                               [`RESOURCE_GROUP`](optimizer-hints.html#optimizer-hints-resource-group)                                               |                                                                                                                                                                                                                               Set resource group during statement execution                                                                                                                                                                                                                               |      Global      |
|                     [`SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery), [`NO_SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery)                     |                                                                                                                                                                                                         Affects semijoin strategies; beginning with MySQL 8.0.17, this also applies to antijoins                                                                                                                                                                                                          |   Query block    |
|                 [`SKIP_SCAN`](optimizer-hints.html#optimizer-hints-index-level), [`NO_SKIP_SCAN`](optimizer-hints.html#optimizer-hints-index-level)                 |                                                                                                                                                                                                                                      Affects Skip Scan optimization                                                                                                                                                                                                                                       |   Table, index   |
|                                                      [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var)                                                      |                                                                                                                                                                                                                                  Set variable during statement execution                                                                                                                                                                                                                                  |      Global      |
|                                                     [`SUBQUERY`](optimizer-hints.html#optimizer-hints-subquery)                                                     |                                                                                                                                                                                                                       Affects materialization, `IN`-to-`EXISTS` subquery stratgies                                                                                                                                                                                                                        |   Query block    |

 Disabling an optimization prevents the optimizer from using it. Enabling an optimization means the optimizer is free to use the strategy if it applies to statement execution, not that the optimizer necessarily uses it.

#### Optimizer Hint Syntax

 MySQL supports comments in SQL statements as described in [Section 9.7, “Comments”](comments.html). Optimizer hints must be specified within `/*+ ... */` comments. That is, optimizer hints use a variant of `/* ... */` C-style comment syntax, with a `+` character following the `/*` comment opening sequence. Examples:

```
/*+ BKA(t1) */
/*+ BNL(t1, t2) */
/*+ NO_RANGE_OPTIMIZATION(t4 PRIMARY) */
/*+ QB_NAME(qb2) */
```

 Whitespace is permitted after the `+` character.

 The parser recognizes optimizer hint comments after the initial keyword of [`SELECT`](select.html), [`UPDATE`](update.html), [`INSERT`](insert.html), [`REPLACE`](replace.html), and [`DELETE`](delete.html) statements. Hints are permitted in these contexts:

* At the beginning of query and data change statements:

  ```
  SELECT /*+ ... */ ...
  INSERT /*+ ... */ ...
  REPLACE /*+ ... */ ...
  UPDATE /*+ ... */ ...
  DELETE /*+ ... */ ...
  ```

* At the beginning of query blocks:

  ```
  (SELECT /*+ ... */ ... )
  (SELECT ... ) UNION (SELECT /*+ ... */ ... )
  (SELECT /*+ ... */ ... ) UNION (SELECT /*+ ... */ ... )
  UPDATE ... WHERE x IN (SELECT /*+ ... */ ...)
  INSERT ... SELECT /*+ ... */ ...
  ```

* In hintable statements prefaced by [`EXPLAIN`](explain.html). For example:

  ```
  EXPLAIN SELECT /*+ ... */ ...
  EXPLAIN UPDATE ... WHERE x IN (SELECT /*+ ... */ ...)
  ```

   The implication is that you can use [`EXPLAIN`](explain.html) to see how optimizer hints affect execution plans. Use [`SHOW WARNINGS`](show-warnings.html) immediately after [`EXPLAIN`](explain.html) to see how hints are used. The extended `EXPLAIN` output displayed by a following [`SHOW WARNINGS`](show-warnings.html) indicates which hints were used. Ignored hints are not displayed.

 A hint comment may contain multiple hints, but a query block cannot contain multiple hint comments. This is valid:

```
SELECT /*+ BNL(t1) BKA(t2) */ ...
```

 But this is invalid:

```
SELECT /*+ BNL(t1) */ /* BKA(t2) */ ...
```

 When a hint comment contains multiple hints, the possibility of duplicates and conflicts exists. The following general guidelines apply. For specific hint types, additional rules may apply, as indicated in the hint descriptions.

* Duplicate hints: For a hint such as `/*+ MRR(idx1) MRR(idx1) */`, MySQL uses the first hint and issues a warning about the duplicate hint.

* Conflicting hints: For a hint such as `/*+ MRR(idx1) NO_MRR(idx1) */`, MySQL uses the first hint and issues a warning about the second conflicting hint.

 Query block names are identifiers and follow the usual rules about what names are valid and how to quote them (see [Section 9.2, “Schema Object Names”](identifiers.html)).

 Hint names, query block names, and strategy names are not case-sensitive. References to table and index names follow the usual identifier case-sensitivity rules (see [Section 9.2.3, “Identifier Case Sensitivity”](identifier-case-sensitivity.html)).

#### Join-Order Optimizer Hints

 Join-order hints affect the order in which the optimizer joins tables.

 Syntax of the [`JOIN_FIXED_ORDER`](optimizer-hints.html#optimizer-hints-join-order) hint:

```
hint_name([@query_block_name])
```

 Syntax of other join-order hints:

```
hint_name([@query_block_name] tbl_name [, tbl_name] ...)
hint_name(tbl_name[@query_block_name] [, tbl_name[@query_block_name]] ...)
```

 The syntax refers to these terms:

* *`hint_name`*: These hint names are permitted:

  * [`JOIN_FIXED_ORDER`](optimizer-hints.html#optimizer-hints-join-order): Force the optimizer to join tables using the order in which they appear in the `FROM` clause. This is the same as specifying `SELECT STRAIGHT_JOIN`.

  * [`JOIN_ORDER`](optimizer-hints.html#optimizer-hints-join-order): Instruct the optimizer to join tables using the specified table order. The hint applies to the named tables. The optimizer may place tables that are not named anywhere in the join order, including between specified tables.

  * [`JOIN_PREFIX`](optimizer-hints.html#optimizer-hints-join-order): Instruct the optimizer to join tables using the specified table order for the first tables of the join execution plan. The hint applies to the named tables. The optimizer places all other tables after the named tables.

  * [`JOIN_SUFFIX`](optimizer-hints.html#optimizer-hints-join-order): Instruct the optimizer to join tables using the specified table order for the last tables of the join execution plan. The hint applies to the named tables. The optimizer places all other tables before the named tables.

* *`tbl_name`*: The name of a table used in the statement. A hint that names tables applies to all tables that it names. The [`JOIN_FIXED_ORDER`](optimizer-hints.html#optimizer-hints-join-order) hint names no tables and applies to all tables in the `FROM` clause of the query block in which it occurs.

   If a table has an alias, hints must refer to the alias, not the table name.

   Table names in hints cannot be qualified with schema names.

* *`query_block_name`*: The query block to which the hint applies. If the hint includes no leading `@*`query_block_name`*`, the hint applies to the query block in which it occurs. For `*`tbl_name`*@*`query_block_name`*` syntax, the hint applies to the named table in the named query block. To assign a name to a query block, see [Optimizer Hints for Naming Query Blocks](optimizer-hints.html#optimizer-hints-query-block-naming).

 Example:

```
SELECT
/*+ JOIN_PREFIX(t2, t5@subq2, t4@subq1)
    JOIN_ORDER(t4@subq1, t3)
    JOIN_SUFFIX(t1) */
COUNT(*) FROM t1 JOIN t2 JOIN t3
           WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4)
             AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5);
```

 Hints control the behavior of semijoin tables that are merged to the outer query block. If subqueries `subq1` and `subq2` are converted to semijoins, tables `t4@subq1` and `t5@subq2` are merged to the outer query block. In this case, the hint specified in the outer query block controls the behavior of `t4@subq1`, `t5@subq2` tables.

 The optimizer resolves join-order hints according to these principles:

* Multiple hint instances

   Only one [`JOIN_PREFIX`](optimizer-hints.html#optimizer-hints-join-order) and [`JOIN_SUFFIX`](optimizer-hints.html#optimizer-hints-join-order) hint of each type are applied. Any later hints of the same type are ignored with a warning. [`JOIN_ORDER`](optimizer-hints.html#optimizer-hints-join-order) can be specified several times.

   Examples:

  ```
  /*+ JOIN_PREFIX(t1) JOIN_PREFIX(t2) */
  ```

   The second [`JOIN_PREFIX`](optimizer-hints.html#optimizer-hints-join-order) hint is ignored with a warning.

  ```
  /*+ JOIN_PREFIX(t1) JOIN_SUFFIX(t2) */
  ```

   Both hints are applicable. No warning occurs.

  ```
  /*+ JOIN_ORDER(t1, t2) JOIN_ORDER(t2, t3) */
  ```

   Both hints are applicable. No warning occurs.

* Conflicting hints

   In some cases hints can conflict, such as when [`JOIN_ORDER`](optimizer-hints.html#optimizer-hints-join-order) and [`JOIN_PREFIX`](optimizer-hints.html#optimizer-hints-join-order) have table orders that are impossible to apply at the same time:

  ```
  SELECT /*+ JOIN_ORDER(t1, t2) JOIN_PREFIX(t2, t1) */ ... FROM t1, t2;
  ```

   In this case, the first specified hint is applied and subsequent conflicting hints are ignored with no warning. A valid hint that is impossible to apply is silently ignored with no warning.

* Ignored hints

   A hint is ignored if a table specified in the hint has a circular dependency.

   Example:

  ```
  /*+ JOIN_ORDER(t1, t2) JOIN_PREFIX(t2, t1) */
  ```

   The [`JOIN_ORDER`](optimizer-hints.html#optimizer-hints-join-order) hint sets table `t2` dependent on `t1`. The [`JOIN_PREFIX`](optimizer-hints.html#optimizer-hints-join-order) hint is ignored because table `t1` cannot be dependent on `t2`. Ignored hints are not displayed in extended [`EXPLAIN`](explain.html) output.

* Interaction with [`const`](explain-output.html#jointype_const) tables

   The MySQL optimizer places `const` tables first in the join order, and the position of a `const` table cannot be affected by hints. References to `const` tables in join-order hints are ignored, although the hint is still applicable. For example, these are equivalent:

  ```
  JOIN_ORDER(t1, const_tbl, t2)
  JOIN_ORDER(t1, t2)
  ```

   Accepted hints shown in extended [`EXPLAIN`](explain.html) output include `const` tables as they were specified.

* Interaction with types of join operations

   MySQL supports several type of joins: `LEFT`, `RIGHT`, `INNER`, `CROSS`, `STRAIGHT_JOIN`. A hint that conflicts with the specified type of join is ignored with no warning.

   Example:

  ```
  SELECT /*+ JOIN_PREFIX(t1, t2) */FROM t2 LEFT JOIN t1;
  ```

   Here a conflict occurs between the requested join order in the hint and the order required by the `LEFT JOIN`. The hint is ignored with no warning.

#### Table-Level Optimizer Hints

 Table-level hints affect:

* Use of the Block Nested-Loop (BNL) and Batched Key Access (BKA) join-processing algorithms (see [Section 8.2.1.12, “Block Nested-Loop and Batched Key Access Joins”](bnl-bka-optimization.html)).

* Whether derived tables, view references, or common table expressions should be merged into the outer query block, or materialized using an internal temporary table.

* Use of the derived table condition pushdown optimization (added in MySQL 8.0.22). See [Section 8.2.2.5, “Derived Condition Pushdown Optimization”](derived-condition-pushdown-optimization.html).

 These hint types apply to specific tables, or all tables in a query block.

 Syntax of table-level hints:

```
hint_name([@query_block_name] [tbl_name [, tbl_name] ...])
hint_name([tbl_name@query_block_name [, tbl_name@query_block_name] ...])
```

 The syntax refers to these terms:

* *`hint_name`*: These hint names are permitted:

  * [`BKA`](optimizer-hints.html#optimizer-hints-table-level), [`NO_BKA`](optimizer-hints.html#optimizer-hints-table-level): Enable or disable bacthed key access for the specified tables.

  * [`BNL`](optimizer-hints.html#optimizer-hints-table-level), [`NO_BNL`](optimizer-hints.html#optimizer-hints-table-level): Enable or disable block nested loop for the specified tables. In MySQL 8.0.18 and later, these hints also enable and disable the hash join optimization.

    Note

     The block-nested loop optimization is removed in MySQL 8.0.20 and later releases, but `BNL` and `NO_BNL` continue to be supported for enabling and disabling hash joins.

  * [`DERIVED_CONDITION_PUSHDOWN`](optimizer-hints.html#optimizer-hints-table-level), [`NO_DERIVED_CONDITION_PUSHDOWN`](optimizer-hints.html#optimizer-hints-table-level): Enable or disable use of derived table condition pushdown for the specified tables (added in MySQL 8.0.22). For more information, see [Section 8.2.2.5, “Derived Condition Pushdown Optimization”](derived-condition-pushdown-optimization.html).

  * [`HASH_JOIN`](optimizer-hints.html#optimizer-hints-table-level), [`NO_HASH_JOIN`](optimizer-hints.html#optimizer-hints-table-level): In MySQL 8.0.18 only, enable or disable use of a hash join for the specified tables. These hints have no effect in MySQL 8.0.19 or later, where you should use [`BNL`](optimizer-hints.html#optimizer-hints-table-level) or [`NO_BNL`](optimizer-hints.html#optimizer-hints-table-level) instead.

  * [`MERGE`](optimizer-hints.html#optimizer-hints-table-level), [`NO_MERGE`](optimizer-hints.html#optimizer-hints-table-level): Enable merging for the specified tables, view references or common table expressions; or disable merging and use materialization instead.

    []()[]()[]()

  Note

   To use a block nested loop or batched key access hint to enable join buffering for any inner table of an outer join, join buffering must be enabled for all inner tables of the outer join.

* *`tbl_name`*: The name of a table used in the statement. The hint applies to all tables that it names. If the hint names no tables, it applies to all tables of the query block in which it occurs.

   If a table has an alias, hints must refer to the alias, not the table name.

   Table names in hints cannot be qualified with schema names.

* *`query_block_name`*: The query block to which the hint applies. If the hint includes no leading `@*`query_block_name`*`, the hint applies to the query block in which it occurs. For `*`tbl_name`*@*`query_block_name`*` syntax, the hint applies to the named table in the named query block. To assign a name to a query block, see [Optimizer Hints for Naming Query Blocks](optimizer-hints.html#optimizer-hints-query-block-naming).

 Examples:

```
SELECT /*+ NO_BKA(t1, t2) */ t1.* FROM t1 INNER JOIN t2 INNER JOIN t3;
SELECT /*+ NO_BNL() BKA(t1) */ t1.* FROM t1 INNER JOIN t2 INNER JOIN t3;
SELECT /*+ NO_MERGE(dt) */ * FROM (SELECT * FROM t1) AS dt;
```

 A table-level hint applies to tables that receive records from previous tables, not sender tables. Consider this statement:

```
SELECT /*+ BNL(t2) */ FROM t1, t2;
```

 If the optimizer chooses to process `t1` first, it applies a Block Nested-Loop join to `t2` by buffering the rows from `t1` before starting to read from `t2`. If the optimizer instead chooses to process `t2` first, the hint has no effect because `t2` is a sender table.

 For the [`MERGE`](optimizer-hints.html#optimizer-hints-table-level) and [`NO_MERGE`](optimizer-hints.html#optimizer-hints-table-level) hints, these precedence rules apply:

* A hint takes precedence over any optimizer heuristic that is not a technical constraint. (If providing a hint as a suggestion has no effect, the optimizer has a reason for ignoring it.)

* A hint takes precedence over the [`derived_merge`](switchable-optimizations.html#optflag_derived-merge) flag of the [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) system variable.

* For view references, an `ALGORITHM={MERGE|TEMPTABLE}` clause in the view definition takes precedence over a hint specified in the query referencing the view.

#### Index-Level Optimizer Hints

 Index-level hints affect which index-processing strategies the optimizer uses for particular tables or indexes. These hint types affect use of Index Condition Pushdown (ICP), Multi-Range Read (MRR), Index Merge, and range optimizations (see [Section 8.2.1, “Optimizing SELECT Statements”](select-optimization.html)).

 Syntax of index-level hints:

```
hint_name([@query_block_name] tbl_name [index_name [, index_name] ...])
hint_name(tbl_name@query_block_name [index_name [, index_name] ...])
```

 The syntax refers to these terms:

* *`hint_name`*: These hint names are permitted:

  * []() []() [`GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level): Enable or disable the specified index or indexes for index scans for `GROUP BY` operations. Equivalent to the index hints `FORCE INDEX FOR GROUP BY`, `IGNORE INDEX FOR GROUP BY`. Available in MySQL 8.0.20 and later.

  * []() []() [`INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_INDEX`](optimizer-hints.html#optimizer-hints-index-level): Acts as the combination of [`JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level), and [`ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level), forcing the server to use the specified index or indexes for any and all scopes, or as the combination of [`NO_JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_GROUP_INDEX`](optimizer-hints.html#optimizer-hints-index-level), and [`NO_ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level), which causes the server to ignore the specified index or indexes for any and all scopes. Equivalent to `FORCE INDEX`, `IGNORE INDEX`. Available beginning with MySQL 8.0.20.

  * []() []() [`INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level), [`NO_INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level): Enable or disable the Index Merge access method for the specified table or indexes. For information about this access method, see [Section 8.2.1.3, “Index Merge Optimization”](index-merge-optimization.html). These hints apply to all three Index Merge algorithms.

     The [`INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) hint forces the optimizer to use Index Merge for the specified table using the specified set of indexes. If no index is specified, the optimizer considers all possible index combinations and selects the least expensive one. The hint may be ignored if the index combination is inapplicable to the given statement.

     The [`NO_INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) hint disables Index Merge combinations that involve any of the specified indexes. If the hint specifies no indexes, Index Merge is not permitted for the table.

  * []() []() [`JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_JOIN_INDEX`](optimizer-hints.html#optimizer-hints-index-level): Forces MySQL to use or ignore the specified index or indexes for any access method, such as `ref`, `range`, [`index_merge`](switchable-optimizations.html#optflag_index-merge), and so on. Equivalent to `FORCE INDEX FOR JOIN`, `IGNORE INDEX FOR JOIN`. Available in MySQL 8.0.20 and later.

  * []() []() [`MRR`](optimizer-hints.html#optimizer-hints-index-level), [`NO_MRR`](optimizer-hints.html#optimizer-hints-index-level): Enable or disable MRR for the specified table or indexes. MRR hints apply only to `InnoDB` and `MyISAM` tables. For information about this access method, see [Section 8.2.1.11, “Multi-Range Read Optimization”](mrr-optimization.html).

  * []() [`NO_ICP`](optimizer-hints.html#optimizer-hints-index-level): Disable ICP for the specified table or indexes. By default, ICP is a candidate optimization strategy, so there is no hint for enabling it. For information about this access method, see [Section 8.2.1.6, “Index Condition Pushdown Optimization”](index-condition-pushdown-optimization.html).

  * []() [`NO_RANGE_OPTIMIZATION`](optimizer-hints.html#optimizer-hints-index-level): Disable index range access for the specified table or indexes. This hint also disables Index Merge and Loose Index Scan for the table or indexes. By default, range access is a candidate optimization strategy, so there is no hint for enabling it.

     This hint may be useful when the number of ranges may be high and range optimization would require many resources.

  * []() []() [`ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level), [`NO_ORDER_INDEX`](optimizer-hints.html#optimizer-hints-index-level): Cause MySQL to use or to ignore the specified index or indexes for sorting rows. Equivalent to `FORCE INDEX FOR ORDER BY`, `IGNORE INDEX FOR ORDER BY`. Available beginning with MySQL 8.0.20.

  * []() []() [`SKIP_SCAN`](optimizer-hints.html#optimizer-hints-index-level), [`NO_SKIP_SCAN`](optimizer-hints.html#optimizer-hints-index-level): Enable or disable the Skip Scan access method for the specified table or indexes. For information about this access method, see [Skip Scan Range Access Method](range-optimization.html#range-access-skip-scan). These hints are available as of MySQL 8.0.13.

     The [`SKIP_SCAN`](optimizer-hints.html#optimizer-hints-index-level) hint forces the optimizer to use Skip Scan for the specified table using the specified set of indexes. If no index is specified, the optimizer considers all possible indexes and selects the least expensive one. The hint may be ignored if the index is inapplicable to the given statement.

     The [`NO_SKIP_SCAN`](optimizer-hints.html#optimizer-hints-index-level) hint disables Skip Scan for the specified indexes. If the hint specifies no indexes, Skip Scan is not permitted for the table.

* *`tbl_name`*: The table to which the hint applies.

* *`index_name`*: The name of an index in the named table. The hint applies to all indexes that it names. If the hint names no indexes, it applies to all indexes in the table.

   To refer to a primary key, use the name `PRIMARY`. To see the index names for a table, use [`SHOW INDEX`](show-index.html).

* *`query_block_name`*: The query block to which the hint applies. If the hint includes no leading `@*`query_block_name`*`, the hint applies to the query block in which it occurs. For `*`tbl_name`*@*`query_block_name`*` syntax, the hint applies to the named table in the named query block. To assign a name to a query block, see [Optimizer Hints for Naming Query Blocks](optimizer-hints.html#optimizer-hints-query-block-naming).

 Examples:

```
SELECT /*+ INDEX_MERGE(t1 f3, PRIMARY) */ f2 FROM t1
  WHERE f1 = 'o' AND f2 = f3 AND f3 <= 4;
SELECT /*+ MRR(t1) */ * FROM t1 WHERE f2 <= 3 AND 3 <= f3;
SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1
  FROM t3 WHERE f1 > 30 AND f1 < 33;
INSERT INTO t3(f1, f2, f3)
  (SELECT /*+ NO_ICP(t2) */ t2.f1, t2.f2, t2.f3 FROM t1,t2
   WHERE t1.f1=t2.f1 AND t2.f2 BETWEEN t1.f1
   AND t1.f2 AND t2.f2 + 1 >= t1.f1 + 1);
SELECT /*+ SKIP_SCAN(t1 PRIMARY) */ f1, f2
  FROM t1 WHERE f2 > 40;
```

 The following examples use the Index Merge hints, but other index-level hints follow the same principles regarding hint ignoring and precedence of optimizer hints in relation to the [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) system variable or index hints.

 Assume that table `t1` has columns `a`, `b`, `c`, and `d`; and that indexes named `i_a`, `i_b`, and `i_c` exist on `a`, `b`, and `c`, respectively:

```
SELECT /*+ INDEX_MERGE(t1 i_a, i_b, i_c)*/ * FROM t1
  WHERE a = 1 AND b = 2 AND c = 3 AND d = 4;
```

 Index Merge is used for `(i_a, i_b, i_c)` in this case.

```
SELECT /*+ INDEX_MERGE(t1 i_a, i_b, i_c)*/ * FROM t1
  WHERE b = 1 AND c = 2 AND d = 3;
```

 Index Merge is used for `(i_b, i_c)` in this case.

```
/*+ INDEX_MERGE(t1 i_a, i_b) NO_INDEX_MERGE(t1 i_b) */
```

[`NO_INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) is ignored because there is a preceding hint for the same table.

```
/*+ NO_INDEX_MERGE(t1 i_a, i_b) INDEX_MERGE(t1 i_b) */
```

[`INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) is ignored because there is a preceding hint for the same table.

 For the [`INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) and [`NO_INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) optimizer hints, these precedence rules apply:

* If an optimizer hint is specified and is applicable, it takes precedence over the Index Merge-related flags of the [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) system variable.

  ```
  SET optimizer_switch='index_merge_intersection=off';
  SELECT /*+ INDEX_MERGE(t1 i_b, i_c) */ * FROM t1
  WHERE b = 1 AND c = 2 AND d = 3;
  ```

   The hint takes precedence over [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch). Index Merge is used for `(i_b, i_c)` in this case.

  ```
  SET optimizer_switch='index_merge_intersection=on';
  SELECT /*+ INDEX_MERGE(t1 i_b) */ * FROM t1
  WHERE b = 1 AND c = 2 AND d = 3;
  ```

   The hint specifies only one index, so it is inapplicable, and the [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) flag (`on`) applies. Index Merge is used if the optimizer assesses it to be cost efficient.

  ```
  SET optimizer_switch='index_merge_intersection=off';
  SELECT /*+ INDEX_MERGE(t1 i_b) */ * FROM t1
  WHERE b = 1 AND c = 2 AND d = 3;
  ```

   The hint specifies only one index, so it is inapplicable, and the [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) flag (`off`) applies. Index Merge is not used.

* The index-level optimizer hints `GROUP_INDEX`, `INDEX`, `JOIN_INDEX`, and `ORDER_INDEX` all take precedence over the equivalent `FORCE INDEX` hints; that is, they cause the `FORCE INDEX` hints to be ignored. Likewise, the `NO_GROUP_INDEX`, `NO_INDEX`, `NO_JOIN_INDEX`, and `NO_ORDER_INDEX` hints all take precedence over any `IGNORE INDEX` equivalents, also causing them to be ignored.

   The index-level optimizer hints `GROUP_INDEX`, `NO_GROUP_INDEX`, `INDEX`,`NO_INDEX`, `JOIN_INDEX`,`NO_JOIN_INDEX`, `ORDER_INDEX`, and `NO_ORDER_INDEX` hints all take precedence over all other optimizer hints, including other index-level optimizer hints. Any other optimizer hints are applied only to the indexes permitted by these.

   The `GROUP_INDEX`, `INDEX`, `JOIN_INDEX`, and `ORDER_INDEX` hints are all equivalent to `FORCE INDEX` and not to `USE INDEX`. This is because using one or more of these hints means that a table scan is used only if there is no way to use one of the named indexes to find rows in the table. To cause MySQL to use the same index or set of indexes as with a given instance of `USE INDEX`, you can use `NO_INDEX`, `NO_JOIN_INDEX`, `NO_GROUP_INDEX`, `NO_ORDER_INDEX`, or some combination of these.

   To replicate the effect that `USE INDEX` has in the query `SELECT a,c FROM t1 USE INDEX FOR ORDER BY (i_a) ORDER BY a`, you can use the `NO_ORDER_INDEX` optimizer hint to cover all indexes on the table except the one that is desired like this:

  ```
  SELECT /*+ NO_ORDER_INDEX(t1 i_b,i_c) */ a,c
      FROM t1
      ORDER BY a;
  ```

   Attempting to combine `NO_ORDER_INDEX` for the table as a whole with `USE INDEX FOR ORDER BY` does not work to do this, because `NO_ORDER_BY` causes `USE INDEX` to be ignored, as shown here:

  ```
  mysql> EXPLAIN SELECT /*+ NO_ORDER_INDEX(t1) */ a,c FROM t1
      ->     USE INDEX FOR ORDER BY (i_a) ORDER BY a\G
  *************************** 1. row ***************************
             id: 1
    select_type: SIMPLE
          table: t1
     partitions: NULL
           type: ALL
  possible_keys: NULL
            key: NULL
        key_len: NULL
            ref: NULL
           rows: 256
       filtered: 100.00
          Extra: Using filesort
  ```

* The `USE INDEX`, `FORCE INDEX`, and `IGNORE INDEX` index hints have higher priority than the [`INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) and [`NO_INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level) optimizer hints.

  ```
  /*+ INDEX_MERGE(t1 i_a, i_b, i_c) */ ... IGNORE INDEX i_a
  ```

  `IGNORE INDEX` takes precedence over [`INDEX_MERGE`](optimizer-hints.html#optimizer-hints-index-level), so index `i_a` is excluded from the possible ranges for Index Merge.

  ```
  /*+ NO_INDEX_MERGE(t1 i_a, i_b) */ ... FORCE INDEX i_a, i_b
  ```

   Index Merge is disallowed for `i_a, i_b` because of `FORCE INDEX`, but the optimizer is forced to use either `i_a` or `i_b` for [`range`](explain-output.html#jointype_range) or [`ref`](explain-output.html#jointype_ref) access. There are no conflicts; both hints are applicable.

* If an `IGNORE INDEX` hint names multiple indexes, those indexes are unavailable for Index Merge.

* The `FORCE INDEX` and `USE INDEX` hints make only the named indexes to be available for Index Merge.

  ```
  SELECT /*+ INDEX_MERGE(t1 i_a, i_b, i_c) */ a FROM t1
  FORCE INDEX (i_a, i_b) WHERE c = 'h' AND a = 2 AND b = 'b';
  ```

   The Index Merge intersection access algorithm is used for `(i_a, i_b)`. The same is true if `FORCE INDEX` is changed to `USE INDEX`.

#### Subquery Optimizer Hints

 Subquery hints affect whether to use semijoin transformations and which semijoin strategies to permit, and, when semijoins are not used, whether to use subquery materialization or `IN`-to-`EXISTS` transformations. For more information about these optimizations, see [Section 8.2.2, “Optimizing Subqueries, Derived Tables, View References, and Common Table Expressions”](subquery-optimization.html).

 Syntax of hints that affect semijoin strategies:

```
hint_name([@query_block_name] [strategy [, strategy] ...])
```

 The syntax refers to these terms:

* *`hint_name`*: These hint names are permitted:

  * [`SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery), [`NO_SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery): Enable or disable the named semijoin strategies.

* *`strategy`*: A semijoin strategy to be enabled or disabled. These strategy names are permitted: `DUPSWEEDOUT`, `FIRSTMATCH`, `LOOSESCAN`, `MATERIALIZATION`.

   For [`SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery) hints, if no strategies are named, semijoin is used if possible based on the strategies enabled according to the [`optimizer_switch`](server-system-variables.html#sysvar_optimizer_switch) system variable. If strategies are named but inapplicable for the statement, `DUPSWEEDOUT` is used.

   For [`NO_SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery) hints, if no strategies are named, semijoin is not used. If strategies are named that rule out all applicable strategies for the statement, `DUPSWEEDOUT` is used.

 If one subquery is nested within another and both are merged into a semijoin of an outer query, any specification of semijoin strategies for the innermost query are ignored. [`SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery) and [`NO_SEMIJOIN`](optimizer-hints.html#optimizer-hints-subquery) hints can still be used to enable or disable semijoin transformations for such nested subqueries.

 If `DUPSWEEDOUT` is disabled, on occasion the optimizer may generate a query plan that is far from optimal. This occurs due to heuristic pruning during greedy search, which can be avoided by setting [`optimizer_prune_level=0`](server-system-variables.html#sysvar_optimizer_prune_level).

 Examples:

```
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) */ * FROM t2
  WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2
  WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
```

 Syntax of hints that affect whether to use subquery materialization or `IN`-to-`EXISTS` transformations:

```
SUBQUERY([@query_block_name] strategy)
```

 The hint name is always [`SUBQUERY`](optimizer-hints.html#optimizer-hints-subquery).

 For [`SUBQUERY`](optimizer-hints.html#optimizer-hints-subquery) hints, these *`strategy`* values are permitted: `INTOEXISTS`, `MATERIALIZATION`.

 Examples:

```
SELECT id, a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) */ a FROM t1) FROM t2;
SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) */ a FROM t1);
```

 For semijoin and [`SUBQUERY`](optimizer-hints.html#optimizer-hints-subquery) hints, a leading `@*`query_block_name`*` specifies the query block to which the hint applies. If the hint includes no leading `@*`query_block_name`*`, the hint applies to the query block in which it occurs. To assign a name to a query block, see [Optimizer Hints for Naming Query Blocks](optimizer-hints.html#optimizer-hints-query-block-naming).

 If a hint comment contains multiple subquery hints, the first is used. If there are other following hints of that type, they produce a warning. Following hints of other types are silently ignored.

#### Statement Execution Time Optimizer Hints

 The [`MAX_EXECUTION_TIME`](optimizer-hints.html#optimizer-hints-execution-time) hint is permitted only for [`SELECT`](select.html) statements. It places a limit *`N`* (a timeout value in milliseconds) on how long a statement is permitted to execute before the server terminates it:

```
MAX_EXECUTION_TIME(N)
```

 Example with a timeout of 1 second (1000 milliseconds):

```
SELECT /*+ MAX_EXECUTION_TIME(1000) */ * FROM t1 INNER JOIN t2 WHERE ...
```

 The [`MAX_EXECUTION_TIME(*`N`*)`](optimizer-hints.html#optimizer-hints-execution-time) hint sets a statement execution timeout of *`N`* milliseconds. If this option is absent or *`N`* is 0, the statement timeout established by the [`max_execution_time`](server-system-variables.html#sysvar_max_execution_time) system variable applies.

 The [`MAX_EXECUTION_TIME`](optimizer-hints.html#optimizer-hints-execution-time) hint is applicable as follows:

* For statements with multiple `SELECT` keywords, such as unions or statements with subqueries, [`MAX_EXECUTION_TIME`](optimizer-hints.html#optimizer-hints-execution-time) applies to the entire statement and must appear after the first [`SELECT`](select.html).

* It applies to read-only [`SELECT`](select.html) statements. Statements that are not read only are those that invoke a stored function that modifies data as a side effect.

* It does not apply to [`SELECT`](select.html) statements in stored programs and is ignored.

#### Variable-Setting Hint Syntax

[]()[]()[]()[]()

 The [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) hint sets the session value of a system variable temporarily (for the duration of a single statement). Examples:

```
SELECT /*+ SET_VAR(sort_buffer_size = 16M) */ name FROM people ORDER BY name;
INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2);
SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=off') */ 1;
```

 Syntax of the [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) hint:

```
SET_VAR(var_name = value)
```

*`var_name`* names a system variable that has a session value (although not all such variables can be named, as explained later). *`value`* is the value to assign to the variable; the value must be a scalar.

[`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) makes a temporary variable change, as demonstrated by these statements:

```
mysql> SELECT @@unique_checks;
+-----------------+
| @@unique_checks |
+-----------------+
|               1 |
+-----------------+
mysql> SELECT /*+ SET_VAR(unique_checks=OFF) */ @@unique_checks;
+-----------------+
| @@unique_checks |
+-----------------+
|               0 |
+-----------------+
mysql> SELECT @@unique_checks;
+-----------------+
| @@unique_checks |
+-----------------+
|               1 |
+-----------------+
```

 With [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var), there is no need to save and restore the variable value. This enables you to replace multiple statements by a single statement. Consider this sequence of statements:

```
SET @saved_val = @@SESSION.var_name;
SET @@SESSION.var_name = value;
SELECT ...
SET @@SESSION.var_name = @saved_val;
```

 The sequence can be replaced by this single statement:

```
SELECT /*+ SET_VAR(var_name = value) ...
```

 Standalone [`SET`](set-variable.html) statements permit any of these syntaxes for naming session variables:

```
SET SESSION var_name = value;
SET @@SESSION.var_name = value;
SET @@.var_name = value;
```

 Because the [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) hint applies only to session variables, session scope is implicit, and `SESSION`, `@@SESSION.`, and `@@` are neither needed nor permitted. Including explicit session-indicator syntax results in the [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) hint being ignored with a warning.

 Not all session variables are permitted for use with [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var). Individual system variable descriptions indicate whether each variable is hintable; see [Section 5.1.8, “Server System Variables”](server-system-variables.html). You can also check a system variable at runtime by attempting to use it with [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var). If the variable is not hintable, a warning occurs:

```
mysql> SELECT /*+ SET_VAR(collation_server = 'utf8') */ 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 4537
Message: Variable 'collation_server' cannot be set using SET_VAR hint.
```

[`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) syntax permits setting only a single variable, but multiple hints can be given to set multiple variables:

```
SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=off')
           SET_VAR(max_heap_table_size = 1G) */ 1;
```

 If several hints with the same variable name appear in the same statement, the first one is applied and the others are ignored with a warning:

```
SELECT /*+ SET_VAR(max_heap_table_size = 1G)
           SET_VAR(max_heap_table_size = 3G) */ 1;
```

 In this case, the second hint is ignored with a warning that it is conflicting.

 A [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) hint is ignored with a warning if no system variable has the specified name or the variable value is incorrect:

```
SELECT /*+ SET_VAR(max_size = 1G) */ 1;
SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=yes') */ 1;
```

 For the first statement, there is no `max_size` variable. For the second statement, [`mrr_cost_based`](switchable-optimizations.html#optflag_mrr-cost-based) takes values of `on` or `off`, so attempting to set it to `yes` is incorrect. In each case, the hint is ignored with a warning.

 The [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) hint is permitted only at the statement level. If used in a subquery, the hint is ignored with a warning.

 Replicas ignore [`SET_VAR`](optimizer-hints.html#optimizer-hints-set-var) hints in replicated statements to avoid the potential for security issues.

#### Resource Group Hint Syntax

 The [`RESOURCE_GROUP`](optimizer-hints.html#optimizer-hints-resource-group) optimizer hint is used for resource group management (see [Section 5.1.16, “Resource Groups”](resource-groups.html)). This hint assigns the thread that executes a statement to the named resource group temporarily (for the duration of the statement). It requires the [`RESOURCE_GROUP_ADMIN`](privileges-provided.html#priv_resource-group-admin) or [`RESOURCE_GROUP_USER`](privileges-provided.html#priv_resource-group-user) privilege.

 Examples:

```
SELECT /*+ RESOURCE_GROUP(USR_default) */ name FROM people ORDER BY name;
INSERT /*+ RESOURCE_GROUP(Batch) */ INTO t2 VALUES(2);
```

 Syntax of the [`RESOURCE_GROUP`](optimizer-hints.html#optimizer-hints-resource-group) hint:

```
RESOURCE_GROUP(group_name)
```

*`group_name`* indicates the resource group to which the thread should be assigned for the duration of statement execution. If the group is nonexistent, a warning occurs and the hint is ignored.

 The [`RESOURCE_GROUP`](optimizer-hints.html#optimizer-hints-resource-group) hint must appear after the initial statement keyword (`SELECT`, `INSERT`, `REPLACE`, `UPDATE`, or `DELETE`).

 An alternative to [`RESOURCE_GROUP`](optimizer-hints.html#optimizer-hints-resource-group) is the [`SET RESOURCE GROUP`](set-resource-group.html) statement, which nontemporarily assigns threads to a resource group. See [Section 13.7.2.4, “SET RESOURCE GROUP Statement”](set-resource-group.html).

#### Optimizer Hints for Naming Query Blocks

 Table-level, index-level, and subquery optimizer hints permit specific query blocks to be named as part of their argument syntax. To create these names, use the [`QB_NAME`](optimizer-hints.html#optimizer-hints-query-block-naming) hint, which assigns a name to the query block in which it occurs:

```
QB_NAME(name)
```

[`QB_NAME`](optimizer-hints.html#optimizer-hints-query-block-naming) hints can be used to make explicit in a clear way which query blocks other hints apply to. They also permit all non-query block name hints to be specified within a single hint comment for easier understanding of complex statements. Consider the following statement:

```
SELECT ...
  FROM (SELECT ...
  FROM (SELECT ... FROM ...)) ...
```

[`QB_NAME`](optimizer-hints.html#optimizer-hints-query-block-naming) hints assign names to query blocks in the statement:

```
SELECT /*+ QB_NAME(qb1) */ ...
  FROM (SELECT /*+ QB_NAME(qb2) */ ...
  FROM (SELECT /*+ QB_NAME(qb3) */ ... FROM ...)) ...
```

 Then other hints can use those names to refer to the appropriate query blocks:

```
SELECT /*+ QB_NAME(qb1) MRR(@qb1 t1) BKA(@qb2) NO_MRR(@qb3t1 idx1, id2) */ ...
  FROM (SELECT /*+ QB_NAME(qb2) */ ...
  FROM (SELECT /*+ QB_NAME(qb3) */ ... FROM ...)) ...
```

 The resulting effect is as follows:

* [`MRR(@qb1 t1)`](optimizer-hints.html#optimizer-hints-index-level) applies to table `t1` in query block `qb1`.

* [`BKA(@qb2)`](optimizer-hints.html#optimizer-hints-table-level) applies to query block `qb2`.

* [`NO_MRR(@qb3 t1 idx1, id2)`](optimizer-hints.html#optimizer-hints-index-level) applies to indexes `idx1` and `idx2` in table `t1` in query block `qb3`.

 Query block names are identifiers and follow the usual rules about what names are valid and how to quote them (see [Section 9.2, “Schema Object Names”](identifiers.html)). For example, a query block name that contains spaces must be quoted, which can be done using backticks:

```
SELECT /*+ BKA(@`my hint name`) */ ...
  FROM (SELECT /*+ QB_NAME(`my hint name`) */ ...) ...
```

 If the [`ANSI_QUOTES`](sql-mode.html#sqlmode_ansi_quotes) SQL mode is enabled, it is also possible to quote query block names within double quotation marks:

```
SELECT /*+ BKA(@"my hint name") */ ...
  FROM (SELECT /*+ QB_NAME("my hint name") */ ...) ...
```

