1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

MDEV-35856: implement index hints

Part of an umbrella task MDEV-33281 for implementing optimizer hints.

This commit introduces hints affecting the use of indexes:
  - JOIN_INDEX, NO_JOIN_INDEX
  - GROUP_INDEX, NO_GROUP_INDEX
  - ORDER_INDEX, NO_ORDER_INDEX
  - INDEX, NO_INDEX

Syntax of index hints:
  hint_name([@query_block_name] tbl_name [index_name [, index_name] ...])
  hint_name(tbl_name@query_block_name [index_name [, index_name] ...])

JOIN_INDEX, NO_JOIN_INDEX: Forces the server to use or ignore the specified
index or indexes for any access method, such as ref, range, index_merge,
and so on. Equivalent to FORCE INDEX FOR JOIN, IGNORE INDEX FOR JOIN.

GROUP_INDEX, NO_GROUP_INDEX: Enable or disable the specified index or indexes
for index scans for GROUP BY operations. Equivalent to the index hints
FORCE INDEX FOR GROUP BY, IGNORE INDEX FOR GROUP BY.

ORDER_INDEX, NO_ORDER_INDEX: Causes the server to use or to ignore
the specified index or indexes for sorting rows. Equivalent to
FORCE INDEX FOR ORDER BY, IGNORE INDEX FOR ORDER BY.

INDEX, NO_INDEX: Acts as the combination of JOIN_INDEX, GROUP_INDEX
and ORDER_INDEX, forcing the server to use the specified index or indexes
for any and all scopes, or as the combination of NO_JOIN_INDEX, NO_GROUP_INDEX
and NO_ORDER_INDEX, which causes the server to ignore the specified index
or indexes for any and all scopes. Equivalent to FORCE INDEX, IGNORE INDEX.

Two kinds of index hints were introduced during implementation:
the global kind for [NO_]INDEX hint, and the non-global kind for all others.

Possible conflicts which will generate warnings:
- for a table level hint
  - a hint of the same type or the opposite kind has already been specified
    for the same table
- for a index level hint
  - the same type of hint has already been specified for the same
    table or for the same index, OR
  - the opposite kind of hint has already been specified for the
    same index
- For a multi index hint like JOIN_INDEX(t1 i1, i2, i3), it conflicts
    with a previous hint if any of the JOIN_INDEX(t1 i1), JOIN_INDEX(t1 i2),
    JOIN_INDEX(t1 i3) conflicts with a previous hint
This commit is contained in:
Oleg Smirnov
2025-05-01 13:38:10 +07:00
committed by Sergei Golubchik
parent 4453d179e4
commit c329c43be7
11 changed files with 1121 additions and 82 deletions

View File

@@ -51,9 +51,14 @@ enum opt_hints_enum
DERIVED_CONDITION_PUSHDOWN_HINT_ENUM,
MERGE_HINT_ENUM,
SPLIT_MATERIALIZED_HINT_ENUM,
INDEX_HINT_ENUM,
JOIN_INDEX_HINT_ENUM,
GROUP_INDEX_HINT_ENUM,
ORDER_INDEX_HINT_ENUM,
MAX_HINT_ENUM // This one must be the last in the list
};
/**
Environment data for the name resolution phase
*/
@@ -121,7 +126,15 @@ public:
keyword_MERGE,
keyword_NO_MERGE,
keyword_SPLIT_MATERIALIZED,
keyword_NO_SPLIT_MATERIALIZED
keyword_NO_SPLIT_MATERIALIZED,
keyword_INDEX,
keyword_NO_INDEX,
keyword_JOIN_INDEX,
keyword_NO_JOIN_INDEX,
keyword_GROUP_INDEX,
keyword_NO_GROUP_INDEX,
keyword_ORDER_INDEX,
keyword_NO_ORDER_INDEX
};
class Token: public Lex_cstring
@@ -389,7 +402,11 @@ private:
};
// index_level_hint_type ::= MRR | NO_RANGE_OPTIMIZATION | NO_ICP | NO_MRR
/*
index_level_hint_type ::= MRR | NO_RANGE_OPTIMIZATION | NO_ICP | NO_MRR |
INDEX | NO_INDEX | JOIN_INDEX | NO_JOIN_INDEX | ORDER_INDEX |
NO_ORDER_INDEX | GROUP_INDEX | NO_GROUP_INDEX
*/
class Index_level_hint_type_cond
{
public:
@@ -398,7 +415,15 @@ private:
return id == TokenID::keyword_MRR ||
id == TokenID::keyword_NO_RANGE_OPTIMIZATION ||
id == TokenID::keyword_NO_ICP ||
id == TokenID::keyword_NO_MRR;
id == TokenID::keyword_NO_MRR ||
id == TokenID::keyword_INDEX ||
id == TokenID::keyword_NO_INDEX ||
id == TokenID::keyword_JOIN_INDEX ||
id == TokenID::keyword_NO_JOIN_INDEX ||
id == TokenID::keyword_ORDER_INDEX ||
id == TokenID::keyword_NO_ORDER_INDEX ||
id == TokenID::keyword_GROUP_INDEX ||
id == TokenID::keyword_NO_GROUP_INDEX;
}
};
class Index_level_hint_type: public TokenChoice<Parser,
@@ -619,18 +644,20 @@ private:
using AND2::AND2;
};
public:
// index_level_hint ::= index_level_hint_type ( index_level_hint_body )
class Index_level_hint: public AND4<Parser,
Index_level_hint_type,
LParen,
Index_level_hint_body,
RParen>
RParen>,
public Printable_parser_rule
{
public:
using AND4::AND4;
bool resolve(Parse_context *pc) const;
void append_args(THD *thd, String *str) const override;
};
@@ -665,6 +692,7 @@ public:
ulonglong get_milliseconds() const;
};
private:
// semijoin_hint_type ::= SEMIJOIN | NO_SEMIJOIN
class Semijoin_hint_type_cond
{