diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2020-12-15 14:38:30 +0300 |
---|---|---|
committer | Sergei Petrunia <psergey@askmonty.org> | 2020-12-15 14:38:30 +0300 |
commit | 066212d16cc2b3995e2c53de9e2f799fdab557bd (patch) | |
tree | 7deef3958cc714172207807f17b4736560cedfe3 /sql/opt_range.cc | |
parent | ac9c6f53a5e1d0637fb390f1cd7b44bd8c38d72e (diff) | |
download | mariadb-git-066212d16cc2b3995e2c53de9e2f799fdab557bd.tar.gz |
MDEV-21958: Query having many NOT-IN clauses running forever
Basic variant of the fix: do not consider conditions in form
unique_key NOT IN (c1,c2...)
to be sargable. If there are only a few constants, the condition
is not selective. If there are a lot constants, the overhead of
processing such a huge range list is not worth it.
(Backport to 10.2)
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index cbf82a20f4a..3a6579b0471 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7158,6 +7158,30 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param, if (array->count > NOT_IN_IGNORE_THRESHOLD || !value_item) DBUG_RETURN(0); + /* + If this is "unique_key NOT IN (...)", do not consider it sargable (for + any index, not just the unique one). The logic is as follows: + - if there are only a few constants, this condition is not selective + (unless the table is also very small in which case we won't gain + anything) + - If there are a lot of constants, the overhead of building and + processing enormous range list is not worth it. + */ + if (param->using_real_indexes) + { + key_map::Iterator it(field->key_start); + uint key_no; + while ((key_no= it.next_bit()) != key_map::Iterator::BITMAP_END) + { + KEY *key_info= ¶m->table->key_info[key_no]; + if (key_info->user_defined_key_parts == 1 && + (key_info->flags & HA_NOSAME)) + { + DBUG_RETURN(0); + } + } + } + /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */ uint i=0; do |