1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

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.
This commit is contained in:
Monty
2022-06-02 19:47:23 +03:00
committed by Oleg Smirnov
parent 6e7376eb59
commit 515b9ad05a
33 changed files with 6187 additions and 2582 deletions

View File

@ -1257,8 +1257,8 @@ EXPLAIN EXTENDED
SELECT * FROM language, country, continent
WHERE country_group = lang_group AND lang_group IS NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE language ALL NULL NULL NULL NULL 6 0.00 Using where
1 SIMPLE country ALL NULL NULL NULL NULL 2 0.00 Using where; Using join buffer (flat, BNL join)
1 SIMPLE language ALL NULL NULL NULL NULL 6 16.67 Using where
1 SIMPLE country ALL NULL NULL NULL NULL 2 50.00 Using where; Using join buffer (flat, BNL join)
1 SIMPLE continent ALL NULL NULL NULL NULL 6 100.00 Using join buffer (incremental, BNL join)
Warnings:
Note 1003 select `test`.`language`.`lang_group` AS `lang_group`,`test`.`language`.`lang` AS `lang`,`test`.`country`.`code` AS `code`,`test`.`country`.`country_group` AS `country_group`,`test`.`continent`.`cont_group` AS `cont_group`,`test`.`continent`.`cont` AS `cont` from `test`.`language` join `test`.`country` join `test`.`continent` where `test`.`country`.`country_group` = `test`.`language`.`lang_group` and `test`.`language`.`lang_group` is null