diff options
author | Sergei Petrunia <sergey@mariadb.com> | 2023-01-26 12:04:28 +0300 |
---|---|---|
committer | Sergei Petrunia <sergey@mariadb.com> | 2023-01-26 12:04:28 +0300 |
commit | 678f2220cc25b3495f1f16fe2732e49a0cd120f8 (patch) | |
tree | 8ed3d31a3510238aeaaefe23ca6f8dfc22d7a3a0 /sql/sql_select.cc | |
parent | 765291d63e0c2a10c513a354e9ecb2e905570775 (diff) | |
download | mariadb-git-bb-10.4-mdev30218-part2.tar.gz |
MDEV-30218: Incorrect optimization for rowid_filtering, correctionbb-10.4-mdev30218-part2
Enable use of Rowid Filter optimization with eq_ref access.
Use the following assumptions:
- Assume index-only access cost is 50% of non-index-only access cost.
- Take into account that "Eq_ref access cache" reduces the number of
lookups eq_ref access will make.
= This means the number of Rowid Filter checks is reduced also
= Eq_ref access cost is computed using that assumption (see
prev_record_reads() call), so we should use it in all cost '
computations.
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index eb54484fa51..217d02bfa8d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7891,7 +7891,27 @@ best_access_path(JOIN *join, (s->table->file->index_flags(start_key->key,0,1) & HA_DO_RANGE_FILTER_PUSHDOWN)) { - double rows= record_count * records; + double rows; + if (type == JT_EQ_REF) + { + /* + Treat EQ_REF access in a special way: + 1. We have no cost for index-only read. Assume its cost is 50% of + the cost of the full read. + + 2. A regular ref access will do #record_count lookups, but eq_ref + has "lookup cache" which reduces the number of lookups made. + The estimation code uses prev_record_reads() call to estimate: + + tmp = prev_record_reads(join_positions, idx, found_ref); + + Set the effective number of rows from "tmp" here. + */ + keyread_tmp= tmp/ 2; + rows= tmp; + } + else + rows= record_count * records; /* If we use filter F with selectivity s the the cost of fetching data @@ -7934,10 +7954,6 @@ best_access_path(JOIN *join, we cannot use filters as the cost calculation below would cause tmp to become negative. The future resultion is to not limit cost with worst_seek. - - We cannot use filter with JT_EQ_REF as in this case 'tmp' is - number of rows from prev_record_read() and keyread_tmp is 0. These - numbers are not usable with rowid filter code. */ double access_cost_factor= MY_MIN((rows - keyread_tmp) / rows, 1.0); if (!(records < s->worst_seeks && @@ -7945,7 +7961,7 @@ best_access_path(JOIN *join, trace_access_idx.add("rowid_filter_skipped", "worst/max seeks clipping"); else if (access_cost_factor <= 0.0) trace_access_idx.add("rowid_filter_skipped", "cost_factor <= 0"); - else if (type != JT_EQ_REF) + else { filter= table->best_range_rowid_filter_for_partial_join(start_key->key, |