mariadb/mysql-test/include/execute_with_statistics.inc
Monty 515b9ad05a Added EQ_REF chaining to the greedy_optimizer
MDEV-28073 Slow query performance in MariaDB when using many table

The idea is to prefer and chain EQ_REF tables (tables that uses an
unique key to find a row) when searching for the best table combination.
This significantly reduces row combinations that has to be examined.
This is optimization is enabled when setting optimizer_prune_level=2
(which is now default).

Implementation:
- optimizer_prune_level has a new level, 2, which enables EQ_REF
  optimization in addition to the pruning done by level 1.
  Level 2 is now default.
- Added JOIN::eq_ref_tables that contains bits of tables that could use
  potentially use EQ_REF access in the query.  This is calculated
  in sort_and_filter_keyuse()

Under optimizer_prune_level=2:
- When the greedy_optimizer notices that the preceding table was an
  EQ_REF table, it tries to add an EQ_REF table next. If an EQ_REF
  table exists, only this one will be considered at this level.
  We also collect all EQ_REF tables chained by the next levels and these
  are ignored on the starting level as we have already examined these.
  If no EQ_REF table exists, we continue as normal.

This optimization speeds up the greedy_optimizer combination test with
~25%

Other things:
- I ported the changes in MySQL 5.7 to greedy_optimizer.test to MariaDB
  to be able to ensure we can handle all cases that MySQL can do.
- I have run all tests with --mysqld=--optimizer_prune_level=1 to verify that
  there where no test changes.
2022-07-26 22:27:29 +07:00

30 lines
772 B
PHP

# include/execute_with_statistics.inc
#
# SUMMARY
#
# Explain and execute the select statment in $query.
# Then report 'Last_query_cost' estimate from the query
# optimizer and total number of 'Handler_read%' when the
# query was executed.
# Intended usage is to verify that there are not regressions
# in either calculated or actuall cost for $query.
#
# USAGE
#
# let $query= <select statement>;
# --source include/execute_with_statistics.inc
#
# EXAMPLE
# t/greedy_optimizer.test
#
eval EXPLAIN $query;
SHOW STATUS LIKE 'Last_query_cost';
FLUSH STATUS;
eval $query;
--disable_warnings
SELECT SUM(variable_value) AS Total_handler_reads
FROM information_schema.session_status
WHERE variable_name LIKE 'Handler_read%';
--enable_warnings