When a hint has a list of index names, for example,
`NO_INDEX(t1 idx1, idx2)`
there is a possibility that some or all of the listed index names will
not be resolved. If none of them are resolved, the hint becomes a table-level
hint, for example, `NO_INDEX(t1)`, which erroneously disables all indexes
of `t1` instead of disabling only some of them.
This commit addresses this issue by adding an additional check: a hint
containing a list of index names is considered resolved only when at least one
of the listed names is resolved successfully.
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
Support for optimizer hints NO_SPLIT_MATERIALIZED and
SPLIT_MATERIALIZED. These hints allow fine-grained control
of the "lateral derived" optimization within a query.
Introduces new overload of hint_table_state function which
tells both a hint's value as well as whether it is present.
This is useful to disambiguate cases that the other version
of hint_table_state cannot, such as when a hint is forcing
a behavior in the optimizer that it would not normally do
and the corresponding optimizer switch is enabled.
Implements and tests the optimizer hints DERIVED_CONDITION_PUSHDOWN
and NO_DERIVED_CONDITION_PUSHDOWN, table-level hints to enable and
disable, respectively, the condition pushdown for derived tables
which is typically controlled by the condition_pushdown_for_derived
optimizer switch.
Implements and tests the optimizer hints MERGE and NO_MERGE, table-level
hints to enable and disable, respectively, the derived_merge optimization
which is typically controlled by the derived_merge optimizer switch.
Sometimes hints need to be fixed before TABLE instances are available, but
after TABLE_LIST instances have been created (as in the cases of MERGE and
NO_MERGE). This commit introduces a new function called
fix_hints_for_derived_table to allow early hint fixing for derived tables,
using only a TABLE_LIST instance (so long as such hints are not index-level).
This commit implements optimizer hints allowing to affect the order
of joining tables:
- JOIN_FIXED_ORDER similar to existing STRAIGHT_JOIN hint;
- JOIN_ORDER to apply the specified table order;
- JOIN_PREFIX to hint what tables should be first in the join;
- JOIN_SUFFIX to hint what tables should be last in the join.
- remove get_args_printer() from hints printing
- add append_hint_arguments(THD *thd, opt_hints_enum hint, String *str)
- add more comments
- rename st_opt_hint_info::hint_name to hint_type
- add pptimizer trace support for hints
- add dbug_print_hints()
- make print_warn() not be a template
- introduce Printable_parser_rule interface, make grammar rules that
emit warnings implement it and print_warn invokes its function)
- remove Parser::Hint::append_args() as it is not used anywhere
(it used to be necessary call print_warn(... (Parser::Hint*)NULL);
It places a limit N (a timeout value in milliseconds) on how long
a statement is permitted to execute before the server terminates it.
Syntax:
SELECT /*+ MAX_EXECUTION_TIME(milliseconds) */ ...
Only top-level SELECT statements support the hint.
- Using Lex_ident_sys to scan identifiers, like the SQL parser does.
This fixes handling of double-quote-delimited and backtick-delimited identifiers,
as well as handling of non-ASCII identifiers.
Unescaping and converting from the client character set to the system
character set is now done using Lex_ident_cli_st and Lex_ident_sys,
like it's done in the SQL tokenizer/parser.
Adding helper methods to_ident_cli() and to_ident_sys()
in Optimizer_hint_parser::Token.
- Fixing the hint parser to report a syntax error when an empty identifiers:
SELECT /*+ BKA(``) */ * FROM t1;
- Moving a part of the code from opt_hints_parser.h to opt_hints_parser.cc
Moving these method definitions:
- Optimizer_hint_tokenizer::find_keyword()
- Optimizer_hint_tokenizer::get_token()
to avoid huge pieces of the code in the header file.
- A Lex_ident_cli_st cleanup
Fixing a few Lex_ident_cli_st methods to return Lex_ident_cli_st &
instead of void, to use them easier in the caller code.
- Fixing the hint parser to display the correct line number
Adding a new data type Lex_comment_st
(a combination of LEX_CSTRING and a line number)
Using it in sql_yacc.yy
- Getting rid of redundant dependencies on sql_hints_parser.h
Moving void LEX::resolve_optimizer_hints() from sql_lex.h to sql_lex.cc
Adding a class Optimizer_hint_parser_output, deriving from
Optimizer_hint_parser::Hint_list. Fixing the hint parser to
return a pointer to an allocated instance of Optimizer_hint_parser_output
rather than an instance of Optimizer_hint_parser::Hint_list.
This allows to use a forward declaration of Optimizer_hint_parser_output
in sql_lex.h and thus avoid dependencies on sql_hints_parser.h.
This commit introduces:
- the infrastructure for optimizer hints;
- hints for join buffering: BNL(), NO_BNL(), BKA(), NO_BKA();
- NO_ICP() hint for disabling index condition pushdown;
- MRR(), MO_MRR() hint for multi-range reads control;
- NO_RANGE_OPTIMIZATION() for disabling range optimization;
- QB_NAME() for assigning names for query blocks.