Details
-
Task
-
Status: Stalled (View Workflow)
-
Major
-
Resolution: Unresolved
Description
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
Optimizer hints in MariaDB
General idea is to be compatible with MySQL.
MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html
1. Hint syntax
Hints are placed after the main statement verb
UPDATE /*+ hints */ table ...; |
DELETE /*+ hints */ FROM table... ; |
SELECT /*+ hints */ ... |
or after the SELECT keyword in any subquery:
SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) |
There can be one or more hints separated with space
hints: hint hint ...
|
Each individual hint is hint name and arguments. In case there are no arguments,
the () brackets are still present:
hint: hint_name([arguments])
|
Incorrect hints produce warnings (a setting to make them errors is not implemented yet).
Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED)
Hints that were incorrect and were ignored are removed from there.
2. Hint hierarchy
(todo: elaborate)
Hints can be
- global - applies to whole query
- table-level - applies to a table
- index-level - applies to an index in a table
2.1 Table-level hints
hint_name([table_name [table_name [,...]] )
|
2.2 Index-level hints
Index-level hints apply to index(es).
Possible syntax variants:
hint_name(table_name [index_name [, index_name] ...])
|
hint_name(table_name@query_block [index_name [, index_name] ...])
|
hint_name(@query_block table_name [index_name [, index_name] ...])
|
3. Query block naming: QB_NAME hint
QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement.
SELECT /*+ QB_NAME(foo) */ select_list FROM ... |
The name can then can be used
- to refer to the query block
- to refer to a table in the query block as table_name@query_block_name.
Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks.
One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL).
Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs)
3.1 select#n names.
Besides the given name, any query block is given a name select#n. It is printed in EXPLAIN EXTENDED output:
Warnings:
|
Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ...
|
At the moment it is NOT yet possible to use it in the hint text:
SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; |
3.2 QB_NAME in CTEs.
What QB_NAME(@name) is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE.
(This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs)
4. Effect of optimizer hints
Optimizer can be controlled by
1. Server variables - optimizer_switch, join_cache_level, etc, etc
2. Old-style hints
3. New-style hints
Old-style hints did not overlap with server variable settings.
New-style hints are more specific than server variable settings, so they override the server variable settings.
Should new-style hints override old-style hints? TODO.
Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like
SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... |
that means:
When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR.
if the query planning is such that use of t1_index1 doesn't allow to use MRR, it won't be used.
The optimizer may also consider using t1_index2 and pick that over using t1_index1.
In such cases the hint is effectively ignored and no warning is given.
Examples: mdev35483-mrr-is-narrow.sql
5. List of hints
5.1 NO_RANGE_OPTIMIZATION hint
It's an index-level hint that disables range optimization for certain index(es):
SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... |
5.2 NO_ICP hint
It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well.
SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... |
5.3 MRR and NO_MRR hints
Index-level hint to force or disable use of MRR.
SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... |
SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... |
This controls
- MRR optimization for range access ( mdev35483-mrr-is-narrow.sql
)
- BKA mdev35483-mrr-controls-bka-partially.sql
5.4 BKA() and NO_BKA() hints
It's a query block or table-level hint.
BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately).
This also enables BKAH. TODO what was the reason for this?
5.5 BNL() and NO_BNL() hints
In MySQL this controls hash join, so in MariaDB it controls BNL-H.
The implementation is "BNL() hint effectively increases join_cache_level up to 4 " .. for the table(s) it applies to)
(FIXED: this seems to fail a fairly trivial example: mdev35483-bnl-fails-why.txt )
5.6 MAX_EXECUTION_TIME() hint
A global-level hint to limit query execution time:
Example:
SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; |
A query that doesn't finish in the time specified will be aborted with an error.
Note: if the @@max_statement_time is set, the hint will be ignored and warning produced.
TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings".
6. Subquery hints
6.1. SUBQUERY hint
Query block-level hint.
SUBQUERY([@query_block_name] MATERIALIZATION)
|
SUBQUERY([@query_block_name] INTOEXISTS)
|
This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join.
6.2 SEMIJOIN, NO_SEMIJOIN
Query block-level hint.
This controls conversion of subquery to semi-join and which semi-join strategies are allowed.
[NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...])
|
where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION.
Attachments
Issue Links
- relates to
-
MDEV-34860 Implement MAX_EXECUTION_TIME hint
-
- Stalled
-
-
MDEV-34888 Implement subquery optimizer hints
-
- In Testing
-
-
MDEV-35504 MySQL 8-style optimizer hints: milestone 1
-
- In Testing
-
-
MDEV-35819 Documentation: versions for Optimizer hints
-
- Confirmed
-
- split from
-
MDEV-33281 Implement optimizer hints like in MySQL 8
-
- In Progress
-
Activity
Field | Original Value | New Value |
---|---|---|
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. Hint hierarchy h2. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. {code:sql} SELECT /*+ QB_NAME(foo) * / select_list FROM ... {code} The name can be used to refer to the hint later. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. Hint hierarchy h2. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. {code:sql} SELECT /*+ QB_NAME(foo) * / select_list FROM ... {code} The name can be used to refer to the hint later. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. {code:sql} SELECT /*+ QB_NAME(foo) * / select_list FROM ... {code} The name can be used to refer to the hint later. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. {code:sql} SELECT /*+ QB_NAME(foo) * / select_list FROM ... {code} The name can be used to refer to the hint later. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can be used to refer to the hint later. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name @ query_block_name}}. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can be used to refer to the hint later. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name @ query_block_name}}. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name @ query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name @ query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. NO_RANGE_OPTIMIZATION hint |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. NO_RANGE_OPTIMIZATION hint |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code} NO_RANGE_OPTIMIZATION(table index1 index2) {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code} NO_RANGE_OPTIMIZATION(table index1 index2) {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "best effort" - if a hint dictates to do something (e.g. {{MRR(t1 t1_index1)}}) but the optimizer doesn't come to the point where it would consider using index {{t1_index1}} in a way that it's possible to use MRR, then the hint will be ignored with no warnings. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. (TODO: what did we decide about the VIEWs) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "best effort" - if a hint dictates to do something (e.g. {{MRR(t1 t1_index1)}}) but the optimizer doesn't come to the point where it would consider using index {{t1_index1}} in a way that it's possible to use MRR, then the hint will be ignored with no warnings. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "best effort" - if a hint dictates to do something (e.g. {{MRR(t1 t1_index1)}}) but the optimizer doesn't come to the point where it would consider using index {{t1_index1}} in a way that it's possible to use MRR, then the hint will be ignored with no warnings. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "best effort" - if a hint dictates to do something (e.g. {{MRR(t1 t1_index1)}}) but the optimizer doesn't come to the point where it would consider using index {{t1_index1}} in a way that it's possible to use MRR, then the hint will be ignored with no warnings. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
Attachment | mdev35483-mrr-is-narrow.sql [ 74268 ] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints . |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA |
Attachment | mdev35483-mrr-controls-bka-partially.sql [ 74269 ] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h2. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h2. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's an index-level hint. h3. BNL() and NO_BNL() hints h3. MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's an index-level hint. h3. BNL() and NO_BNL() hints h3. MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's an index-level hint. h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's an index-level hint. h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. This hint also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. This hint also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
Attachment | mdev35483-no-bka-enables-hash-join.txt [ 74272 ] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? [^mdev35483-no-bka-enables-hash-join.txt] h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? [^mdev35483-no-bka-enables-hash-join.txt] h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? [^mdev35483-no-bka-enables-hash-join.txt] h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? [^mdev35483-no-bka-enables-hash-join.txt] h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... FROM... ; {code} Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? [^mdev35483-no-bka-enables-hash-join.txt] h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable hash index?? [^mdev35483-no-bka-enables-hash-join.txt] h3. 5.5 BNL() and NO_BNL() hints h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO any thing else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: can one control SELECTs inside VIEWs that way? No?) (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. TODO: this seems to fail a fairly trivial example: h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
Attachment | mdev35483-bnl-fails-why.txt [ 74273 ] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. TODO: this seems to fail a fairly trivial example: h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? NO_BKA() seems to enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. It controls choice of one of the two possible strategies. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO]_SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. It controls choice of one of the two possible strategies. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO]_SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO]_SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO]_SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) Besides the given name, any query block is given a name {{select#n}}, so one can refer to it like so: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} (TODO: QB_NAME in CTEs that are used in multiple places?) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy h3. 2.1 Index-level hints Index-level hints apply to index(es). The syntax is {code} hint_name(table_name [index_name [, index_name] ...]) {code} where table_name may be query_block@table_name. (TODO: MySQL also supports hint_name(@query_block_name tbl_name) ? But we don't? ) h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block hint_name(table_name@query_block [index_name [, index_name] ...]) [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block hint_name(table_name@query_block [index_name [, index_name] ...]) [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} This is a global hint. It limits query execution time. A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can later be used * to refer to a query block, where required * to refer to a table as {{table_name@query_block_name}}. Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings. (TODO anything else?) Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? TODO: NO_BKA() seems to lso enable BNL-H: [^mdev35483-no-bka-enables-hash-join.txt] ? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Attachment | mdev35483-no-bka-enables-hash-join.txt [ 74272 ] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) h3. 2.1 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) Hints can be global, table-level, or index-level. h3. 2.1 Table-level hints {code} hint_name(table_name [index_name [, index_name] ...]) {code} h3. 2.2 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) Hints can be global, table-level, or index-level. h3. 2.1 Table-level hints {code} hint_name(table_name [index_name [, index_name] ...]) {code} h3. 2.2 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) Hints can be * global - applies to whole query * table-level - applies to a table * index-level - applies to an index in a table h3. 2.1 Table-level hints {code} hint_name([table_name [table_name [,...]] ) {code} h3. 2.2 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Link | This issue relates to MDEV-35504 [ MDEV-35504 ] |
Link | This issue relates to MDEV-33281 [ MDEV-33281 ] |
Assignee | Sergei Petrunia [ psergey ] |
Fix Version/s | 11.8 [ 29921 ] |
Component/s | Optimizer [ 10200 ] |
Labels | documentation |
Status | Open [ 1 ] | In Progress [ 3 ] |
Fix Version/s | N/A [ 14700 ] | |
Fix Version/s | 11.8 [ 29921 ] |
Link | This issue is part of MENT-51 [ MENT-51 ] |
Description |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) Hints can be * global - applies to whole query * table-level - applies to a table * index-level - applies to an index in a table h3. 2.1 Table-level hints {code} hint_name([table_name [table_name [,...]] ) {code} h3. 2.2 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " TODO: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ? h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
This is a self-contained description of Optimizer Hints in MariaDB, whatever is already implemented in the current patch.
h1. Optimizer hints in MariaDB General idea is to be compatible with MySQL. MySQL hint docs: https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html h2. 1. Hint syntax Hints are placed after the main statement verb {code:sql} UPDATE /*+ hints */ table ...; DELETE /*+ hints */ FROM table... ; SELECT /*+ hints */ ... {code} or after the SELECT keyword in any subquery: {code:sql} SELECT * FROM t1 WHERE a IN (SELECT /*+ hints */ ...) {code} There can be one or more hints separated with space {code} hints: hint hint ... {code} Each individual hint is hint name and arguments. In case there are no arguments, the () brackets are still present: {code} hint: hint_name([arguments]) {code} Incorrect hints produce warnings (a setting to make them errors is not implemented yet). Hints that are not ignored are kept in the query text (you can see them in SHOW PROCESSLIST, Slow Query Log, EXPLAIN EXTENDED) Hints that were incorrect and were ignored are removed from there. h2. 2. Hint hierarchy (todo: elaborate) Hints can be * global - applies to whole query * table-level - applies to a table * index-level - applies to an index in a table h3. 2.1 Table-level hints {code} hint_name([table_name [table_name [,...]] ) {code} h3. 2.2 Index-level hints Index-level hints apply to index(es). Possible syntax variants: {code} hint_name(table_name [index_name [, index_name] ...]) hint_name(table_name@query_block [index_name [, index_name] ...]) hint_name(@query_block table_name [index_name [, index_name] ...]) {code} h2. 3. Query block naming: QB_NAME hint QB_NAME hint is used to assign a name to the query block the hint is in. The Query Block is either a SELECT or a top-level construct of UPDATE or DELETE statement. {code:sql} SELECT /*+ QB_NAME(foo) */ select_list FROM ... {code} The name can then can be used * to refer to the query block * to refer to a table in the query block as {{table_name@query_block_name}}. Query block scope is the whole statement. It is invalid to use the same name for multiple query blocks. One can refer to the query block "down into subquery", "down into derived table", "up to the parent" and "to a right sibling in the UNION". One cannot refer "to a left sibling in a UNION" (It's the same in MySQL). Hints inside VIEWs are not supported, yet. One can neither use hints in VIEW definitions, nor control query plans inside non-merged VIEWs (This is because QB_NAME binding is done "early", before we know that some tables are VIEWs) h3. 3.1 select#n names. Besides the given name, any query block is given a name {{select#n}}. It is printed in EXPLAIN EXTENDED output: {code} Warnings: Note 1003 select /*+ NO_RANGE_OPTIMIZATION(`t3`@`select#1` `PRIMARY`) */ ... {code} *At the moment it is NOT yet possible to use it in the hint text*: {code:sql} SELECT /*+ BKA(tbl1@`select#1`) */ 1 FROM tbl1 ...; {code} h3. 3.2 QB_NAME in CTEs. What {{QB_NAME(@name)}} is used in a CTE which is then used in multiple places? Hints that control @name will control the first use of the CTE. (This "just happens" due to the way CTEs are implemented. We could address it when addressing VIEWs) h2. 4. Effect of optimizer hints Optimizer can be controlled by 1. Server variables - optimizer_switch, join_cache_level, etc, etc 2. Old-style hints 3. New-style hints Old-style hints did not overlap with server variable settings. New-style hints are more specific than server variable settings, so they override the server variable settings. Should new-style hints override old-style hints? TODO. Hints are "narrowly interpreted" and "best effort" - if a hint dictates to do something, like {code:sql} SELECT /*+ MRR(t1 t1_index1) */ ... FROM t1 ... {code} that means: {quote} When considering a query plan that involves using t1_index1 in a way that one can use MRR, use MRR. {quote} if the query planning is such that use of {{t1_index1}} doesn't allow to use MRR, it won't be used. The optimizer may also consider using {{t1_index2}} and pick that over using {{t1_index1}}. In such cases the hint is effectively ignored and no warning is given. Examples: [^mdev35483-mrr-is-narrow.sql] h2. 5. List of hints h3. 5.1 NO_RANGE_OPTIMIZATION hint It's an index-level hint that disables range optimization for certain index(es): {code:sql} SELECT /*+ NO_RANGE_OPTIMIZATION(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.2 NO_ICP hint It's an index-level hint that disables Index Condition Pushdown for the indexes. ICP+BKA is disabled as well. {code:sql} SELECT /*+ NO_ICP(tbl index1 index2) */ * FROM tbl ... {code} h3. 5.3 MRR and NO_MRR hints Index-level hint to force or disable use of MRR. {code:sql} SELECT /*+ MRR(tbl index1 index2) */ * FROM tbl ... SELECT /*+ NO_MRR(tbl index1 index2) */ * FROM tbl ... {code} This controls * MRR optimization for range access ( [^mdev35483-mrr-is-narrow.sql] ) * BKA [^mdev35483-mrr-controls-bka-partially.sql] h3. 5.4 BKA() and NO_BKA() hints It's a query block or table-level hint. BKA() also enables MRR to make BKA possible. (This is different from session variables, where one needs to enable MRR separately). This also enables BKAH. TODO what was the reason for this? h3. 5.5 BNL() and NO_BNL() hints In MySQL this controls hash join, so in MariaDB it controls BNL-H. The implementation is "BNL() hint effectively increases join_cache_level up to 4 " .. for the table(s) it applies to) (FIXED: this seems to fail a fairly trivial example: [^mdev35483-bnl-fails-why.txt] ) h3. 5.6 MAX_EXECUTION_TIME() hint A global-level hint to limit query execution time: Example: {code:sql} SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ... ; {code} A query that doesn't finish in the time specified will be aborted with an error. Note: if the {{@@max_statement_time}} is set, the hint will be ignored and warning produced. TODO: This contradicts with the stated principle that "New-style hints are more specific than server variable settings, so they override the server variable settings". h2. 6. Subquery hints h3. 6.1. SUBQUERY hint Query block-level hint. {code} SUBQUERY([@query_block_name] MATERIALIZATION) SUBQUERY([@query_block_name] INTOEXISTS) {code} This controls non-semi-join subqueries. The parameter specifies which subquery to use. Use of this hint disables conversion of subquery into semi-join. h3. 6.2 SEMIJOIN, NO_SEMIJOIN Query block-level hint. This controls conversion of subquery to semi-join and which semi-join strategies are allowed. {code} [NO_]SEMIJOIN([@query_block_name] [strategy [, strategy] ...]) {code} where strategy is one of DUPSWEEDOUT, FIRSTMATCH, LOOSESCAN, MATERIALIZATION. |
Link | This issue relates to MDEV-34888 [ MDEV-34888 ] |
Link | This issue relates to MDEV-34860 [ MDEV-34860 ] |
Link | This issue relates to MDEV-35819 [ MDEV-35819 ] |
Link | This issue split from MDEV-33281 [ MDEV-33281 ] |
Link | This issue relates to MDEV-33281 [ MDEV-33281 ] |
Status | In Progress [ 3 ] | Stalled [ 10000 ] |
Documented so far on https://mariadb.com/kb/en/optimizer-hints