diff options
author | unknown <sanja@askmonty.org> | 2013-04-18 22:22:04 +0300 |
---|---|---|
committer | unknown <sanja@askmonty.org> | 2013-04-18 22:22:04 +0300 |
commit | 9441e536535af3e71aaa81801645ab42bd07e89f (patch) | |
tree | 4479a5d77e53380b7bd2d9b3d4db3c271ea6b40a /sql/opt_range.cc | |
parent | 8c71e7a38358c79e1b5b9072fa7407cec3cfd273 (diff) | |
download | mariadb-git-9441e536535af3e71aaa81801645ab42bd07e89f.tar.gz |
MDEV-4345
Sampling of selectivity of LIKE predicate.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c29a888ea6f..b736f898768 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3530,7 +3530,74 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) } } } - } + } + + /* Calculate selectivity of probably highly selective predicates */ + ulong check_rows= + min(thd->variables.optimizer_selectivity_sampling_limit, + (ulong) (table_records * SELECTIVITY_SAMPLING_SHARE)); + if (cond && check_rows > SELECTIVITY_SAMPLING_THRESHOLD && + thd->variables.optimizer_use_condition_selectivity > 4) + { + find_selective_predicates_list_processor_data *dt= + (find_selective_predicates_list_processor_data *) + alloc_root(thd->mem_root, + sizeof(find_selective_predicates_list_processor_data)); + if (!dt) + DBUG_RETURN(TRUE); + dt->list.empty(); + dt->table= table; + if (cond->walk(&Item::find_selective_predicates_list_processor, 0, + (uchar*) dt)) + DBUG_RETURN(TRUE); + if (dt->list.elements > 0) + { + check_rows= check_selectivity(thd, check_rows, table, &dt->list); + if (check_rows > SELECTIVITY_SAMPLING_THRESHOLD) + { + COND_STATISTIC *stat; + List_iterator_fast<COND_STATISTIC> it(dt->list); + double examined_rows= check_rows; + while ((stat= it++)) + { + if (!stat->positive) + { + DBUG_PRINT("info", ("To avoid 0 assigned 1 to the counter")); + stat->positive= 1; // avoid 0 + } + DBUG_PRINT("info", ("The predicate selectivity : %g", + (double)stat->positive / examined_rows)); + double selectivity= ((double)stat->positive) / examined_rows; + table->cond_selectivity*= selectivity; + /* + If a field is involved then we register its selectivity in case + there in an equality with the field. + For example in case + t1.a LIKE "%bla%" and t1.a = t2.b + the selectivity we have found could be used also for t2. + */ + if (stat->field_arg) + { + stat->field_arg->cond_selectivity*= selectivity; + + if (stat->field_arg->next_equal_field) + { + for (Field *next_field= stat->field_arg->next_equal_field; + next_field != stat->field_arg; + next_field= next_field->next_equal_field) + { + next_field->cond_selectivity*= selectivity; + next_field->table->cond_selectivity*= selectivity; + } + } + } + } + + } + /* This list and its elements put to mem_root so should not be freed */ + table->cond_selectivity_sampling_explain= &dt->list; + } + } DBUG_RETURN(FALSE); } |