1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-33281 Optimizer hints cleanup:

- add a comment that opt_hints_global->check_unresolved() is never called
- improve comments
- rename everything with "resolved_children" to "fully_resolved_children"
- Opt_hints_table::adjust_key_hints() now returns value
- less "reach-back-to-parent" logic
- rename Hint "adjustment" and "resolution" (yes, both terms were used)
     to "fixing". "Resolution" is already used for parse-tree objects
This commit is contained in:
Sergei Petrunia
2024-12-06 14:12:26 +02:00
committed by Oleg Smirnov
parent 2c8f6058c1
commit d2918e10fc
3 changed files with 104 additions and 69 deletions

View File

@@ -32,31 +32,39 @@
This process
- Creates interpreted hint structures: Opt_hints_global, Opt_hints_qb,
Opt_hints_table, Opt_hints_key.
- Interprets QB_NAME hints and assigns Query Block names.
- Interprets QB_NAME hints and assigns Opt_hints_qb objects their names.
- Table-level hints are put into their Query Block's Opt_hints_qb object.
- Index-level hints are put into their table's Opt_hints_table object.
== Hint "adjustment" ==
Currently, this process is done at the parser stage. (This is one of the
causes why hints do not work across VIEW bounds, here or in MySQL).
During Name Resolution, setup_tables() calls adjust_hints_for_table() for
each table and sets TABLE_LIST::opt_hints_table to point to its
Opt_hints_table.
== Hint "fixing" ==
During Name Resolution, hints are attached the real objects they control:
- table-level hints find their tables,
- index-level hints find their indexes.
This is done in setup_tables() which calls fix_hints_for_table() for
each table, as a result TABLE_LIST::opt_hints_table points to the table's
hints.
== Hint hierarchy ==
Hints have this hierarchy, parent to child:
Hints have this hierarchy, less specific to more specific:
Opt_hints_global
Opt_hints_qb
Opt_hints_table
Opt_hints_key
For some hints, one needs to check the hint's base object and its parent. For
example, MRR can be disabled on a per-index or a per-table basis.
Some hints can be specified at a specific level (e.g. per-index) or at a
more general level (e.g. per-table). When checking the hint, we need
to check for per-index commands and then maybe per-table command.
== How the optimizer checks hints ==
== API for checking hints ==
The optimizer checks what hints specify using these calls:
The optimizer checks hints' instructions using these calls:
hint_table_state()
hint_table_state_or_fallback()
hint_key_state()
@@ -212,9 +220,13 @@ private:
Mem_root_array<Opt_hints*, true> child_array;
/* true if hint is connected to the real object */
bool resolved;
/* Number of resolved children */
uint resolved_children;
bool fixed;
/*
Number of child hints that are fully fixed, that is, fixed and
have all their children also fully fixed.
*/
uint n_fully_fixed_children;
public:
@@ -222,7 +234,7 @@ public:
Opt_hints *parent_arg,
MEM_ROOT *mem_root_arg)
: name(name_arg), parent(parent_arg), child_array(mem_root_arg),
resolved(false), resolved_children(0)
fixed(false), n_fully_fixed_children(0)
{ }
bool is_specified(opt_hints_enum type_arg) const
@@ -274,14 +286,14 @@ public:
}
void set_name(const Lex_ident_sys &name_arg) { name= name_arg; }
Opt_hints *get_parent() const { return parent; }
void set_resolved() { resolved= true; }
bool is_resolved() const { return resolved; }
void incr_resolved_children() { resolved_children++; }
void set_fixed() { fixed= true; }
bool is_fixed() const { return fixed; }
void incr_fully_fixed_children() { n_fully_fixed_children++; }
Mem_root_array<Opt_hints*, true> *child_array_ptr() { return &child_array; }
bool is_all_resolved() const
bool are_children_fully_fixed() const
{
return child_array.size() == resolved_children;
return child_array.size() == n_fully_fixed_children;
}
void register_child(Opt_hints* hint_arg)
@@ -306,12 +318,12 @@ public:
*/
void print(THD *thd, String *str);
/**
Check if there are any unresolved hint objects and
Check if there are any unfixed hint objects and
print warnings for them.
@param thd Pointer to THD object
*/
void check_unresolved(THD *thd);
void check_unfixed(THD *thd);
virtual void append_name(THD *thd, String *str)= 0;
/**
@@ -335,18 +347,18 @@ private:
*/
void append_hint_type(String *str, opt_hints_enum type);
/**
Print warning for unresolved hint name.
Print warnings abount unfixed hints in this hint collection
@param thd Pointer to THD object
*/
void print_warn_unresolved(THD *thd);
void print_unfixed_warnings(THD *thd);
protected:
/**
Override this function in descendants so that print_warn_unresolved()
prints the proper warning text for table/index level unresolved hints
Override this function in descendants so that print_unfixed_warnings()
prints the proper warning text for table/index level unfixed hints
*/
virtual uint get_warn_unresolved_code() const
virtual uint get_unfixed_warning_code() const
{
DBUG_ASSERT(0);
return 0;
@@ -384,7 +396,7 @@ public:
max_exec_time_hint, _1, _2);
}
bool resolve(THD *thd);
bool fix_hint(THD *thd);
};
@@ -466,8 +478,8 @@ public:
@return pointer Opt_hints_table object if this object is found,
NULL otherwise.
*/
Opt_hints_table *adjust_hints_for_table(TABLE *table,
const Lex_ident_table &alias);
Opt_hints_table *fix_hints_for_table(TABLE *table,
const Lex_ident_table &alias);
/**
Returns whether semi-join is enabled for this query block
@@ -548,9 +560,9 @@ public:
@param table Pointer to TABLE object
*/
void adjust_key_hints(TABLE *table);
bool fix_hint(TABLE *table);
virtual uint get_warn_unresolved_code() const override
virtual uint get_unfixed_warning_code() const override
{
return ER_UNRESOLVED_TABLE_HINT_NAME;
}
@@ -584,7 +596,7 @@ public:
append_identifier(thd, str, &name);
}
virtual uint get_warn_unresolved_code() const override
virtual uint get_unfixed_warning_code() const override
{
return ER_UNRESOLVED_INDEX_HINT_NAME;
}