- Before any multiple add() calls, always use (if trace_started()).
- Add unlikely() around all tests of trace_started().
- Change trace.add(); trace.add(); to trace.add().add();
- When trace.add() goes over several line, use the following formating:
trace.
add(xxx).
add(yyy).
add(zzz);
This format was choosen after a discussion between Sergei Petrunia and
me as it looks similar indepedent if 'trace' is an object or a
pointer. It also more suitable for an editors auto-indentation.
Other things:
Added DBUG_ASSERT(thd->trace_started()) to a few functions that should
only be called if trace is enabled.
"use_roworder_index_merge: true" changed to "use_sort_index_merge: false"
As the original output was often not correct.
Also fixed the related 'cause' to be correct.
In best_access_path() print the cost (and number of rows) before
checking if it the plan should be used. This removes the need to print
the cost in two places.
Changed a few "read_time" tags to "cost".
The old code did not't correctly add TIME_FOR_COMPARE to rows that are
part of the scan that will be compared with the attached where clause.
Now the cost calculation for hash join and full join cache join are
identical except for HASH_FANOUT (10%)
The cost for a join with keys is now also uniform.
The total cost for a using a key for lookup is calculated in one place as:
(cost_of_finding_rows_through_key(records) + records/TIME_FOR_COMPARE)*
record_count_of_previous_row_combinations + startup_cost
startup_cost is the cost of a creating a temporary table (if needed)
Best_cost now includes the cost of comparing all WHERE clauses and also
cost of joining with previous row combinations.
Other things:
- Optimizer trace is now printing the total costs, including testing the
WHERE clause (TIME_FOR_COMPARE) and comparing with all previous rows.
- In optimizer trace, include also total cost of query together with the
final join order. This makes it easier to find out where the cost was
calculated.
- Old code used filter even if the cost for it was higher than not using a
filter. This is not corrected.
- When rebasing on 10.11, I noticed some changes to access_cost_factor
calculation. These changes was not picked as the coming changes
to filtering will make that code obsolete.
No code logic changes was done
a -> gain
b -> cost_of_building_range_filter
a_adj -> gain_adj
r -> row_combinations
Other things:
- Optimized the layout of class Range_rowid_filter_cost_info.
One effect was that I moved key_no to the private section to get
better alignment and had to introduce a get_key_no() function.
- Indentation changes in rowid_filter.cc to avoid long rows.
- Updated comments
- Added some extra DEBUG
- Indentation changes and break long lines
- Trivial code changes like:
- Combining 2 statements in one
- Reorder DBUG lines
- Use a variable to store a pointer that is used multiple times
- Moved declaration of variables to start of loop/function
- Removed dead or commented code
- Removed wrong DBUG_EXECUTE code in best_extension_by_limited_search()
In mysql_execute_command(), move optimizer trace initialization to be
after run_set_statement_if_requested() call.
Unfortunately, mysql_execute_command() code uses "goto error" a lot, and
this means optimizer trace code cannot use RAII objects. Work this around
by:
- Make Opt_trace_start a non-RAII object, add init() method.
- Move the code that writes the top-level object and array into
Opt_trace_start::init().
- Print the rowid filters that are available for use with each table.
- Make print_best_access_for_table() print which filter it has picked.
- Make best_access_path() print the filter for considered ref accesses.
- Move testing of my_writer to inline functions to avoid calls
- Made more functions inline. Especially thd->thread_started()
is now very optimized!
- Moved Opt_trace_stmt classe to opt_trace_context.h to get critical
functions inline
- Added unlikely() to optimize for not having optimizer trace enabled
- Made THD::trace_started() inline
- Added 'if (trace_enabled())' around some potentially expensive code
(not many found)
- Added ASSERT's to ensure we don't call expensive optimizer trace calls
if optimizer trace is not enabled
- Added length to Json_writer functions to speed up buffer writes
when optimizer trace is enabled.
- Changed LEX_CSTRING argument handling to not send full struct to writer
function on_add_str() functions now trusts length arguments
This task involves the implementation for the optimizer trace.
This feature produces a trace for any SELECT/UPDATE/DELETE/,
which contains information about decisions taken by the optimizer during
the optimization phase (choice of table access method, various costs,
transformations, etc). This feature would help to tell why some decisions were
taken by the optimizer and why some were rejected.
Trace is session-local, controlled by the @@optimizer_trace variable.
To enable optimizer trace we need to write:
set @@optimizer_trace variable= 'enabled=on';
To display the trace one can run:
SELECT trace FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
This task also involves:
MDEV-18489: Limit the memory used by the optimizer trace
introduces a switch optimizer_trace_max_mem_size which limits
the memory used by the optimizer trace. This was implemented by
Sergei Petrunia.