From aab3c9febc37fdf8b29d6a484d8f3f48a29dd92d Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 17 Mar 2013 12:02:11 -0700 Subject: [PATCH 1/3] Fixed a typo that caused a wrong calculation of the selectivity for pushed down condtions. --- mysql-test/r/selectivity.result | 2 +- mysql-test/r/selectivity_innodb.result | 2 +- sql/sql_select.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index 3db8da46ea2..9d38bd3c976 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -84,7 +84,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 4.17 Using where 2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where -4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where +4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 15.14 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index 0a6abfd66d3..18cd35f2892 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -87,7 +87,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 4.17 Using where 2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where -4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where +4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 14.37 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2 Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bc9e05fe2d9..b6e21a3b8a9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6989,7 +6989,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, if (s->quick && s->quick->index != MAX_KEY) { /* A range scan by index s->quick->index is used to access table s */ - sel*= table_records/table->quick_rows[s->quick->index]; + sel*= table->quick_rows[s->quick->index]/table_records; } else if (ref) { From 8ab81843cd5afef3a2905d9c802168a048de35c7 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 20 Mar 2013 01:00:25 -0700 Subject: [PATCH 2/3] Fixed some bugs in the function that calculated the selectivity of the table conditions. --- sql/opt_range.cc | 115 ++++++++++++++++++++++++---------------------- sql/sql_select.cc | 7 ++- 2 files changed, 65 insertions(+), 57 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 364b01aebb2..d143101a92f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3324,60 +3324,64 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) table->cond_selectivity= 1.0; - if (bitmap_is_clear_all(used_fields)) - DBUG_RETURN(FALSE); - - PARAM param; - MEM_ROOT alloc; - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, - MYF(MY_THREAD_SPECIFIC)); - param.thd= thd; - param.mem_root= &alloc; - param.old_root= thd->mem_root; - param.table= table; - param.is_ror_scan= FALSE; - - if (create_key_parts_for_pseudo_indexes(¶m, used_fields)) + if (!bitmap_is_clear_all(used_fields)) { - free_root(&alloc, MYF(0)); - DBUG_RETURN(FALSE); - } + PARAM param; + MEM_ROOT alloc; + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + MYF(MY_THREAD_SPECIFIC)); + param.thd= thd; + param.mem_root= &alloc; + param.old_root= thd->mem_root; + param.table= table; + param.is_ror_scan= FALSE; - param.prev_tables= param.read_tables= 0; - param.current_table= table->map; - param.using_real_indexes= FALSE; - param.real_keynr[0]= 0; - param.alloced_sel_args= 0; - - thd->no_errors=1; // Don't warn about NULL - - SEL_TREE *tree; - SEL_ARG **key, **end; - uint idx= 0; - - tree= get_mm_tree(¶m, cond); - - if (!tree) - goto end; - - - for (key= tree->keys, end= key + param.keys; key != end; key++, idx++) - { - double rows; - if (*key) + if (create_key_parts_for_pseudo_indexes(¶m, used_fields)) { - rows= records_in_column_ranges(¶m, idx, *key); - if (rows != HA_POS_ERROR) - (*key)->field->cond_selectivity= rows/table_records; + free_root(&alloc, MYF(0)); + DBUG_RETURN(FALSE); } - } - for (Field **field_ptr= table->field; *field_ptr; field_ptr++) - { - Field *table_field= *field_ptr; - if (bitmap_is_set(table->read_set, table_field->field_index) && - table_field->cond_selectivity < 1.0) - table->cond_selectivity*= table_field->cond_selectivity; + param.prev_tables= param.read_tables= 0; + param.current_table= table->map; + param.using_real_indexes= FALSE; + param.real_keynr[0]= 0; + param.alloced_sel_args= 0; + + thd->no_errors=1; // Don't warn about NULL + + SEL_TREE *tree; + SEL_ARG **key, **end; + uint idx= 0; + + tree= get_mm_tree(¶m, cond); + + if (!tree) + goto free_alloc; + + for (key= tree->keys, end= key + param.keys; key != end; key++, idx++) + { + double rows; + if (*key) + { + rows= records_in_column_ranges(¶m, idx, *key); + if (rows != HA_POS_ERROR) + (*key)->field->cond_selectivity= rows/table_records; + } + } + + for (Field **field_ptr= table->field; *field_ptr; field_ptr++) + { + Field *table_field= *field_ptr; + if (bitmap_is_set(table->read_set, table_field->field_index) && + table_field->cond_selectivity < 1.0) + table->cond_selectivity*= table_field->cond_selectivity; + } + + free_alloc: + thd->mem_root= param.old_root; + free_root(&alloc, MYF(0)); + } /* Calculate the selectivity of the range conditions supported by indexes */ @@ -3412,17 +3416,18 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) } if (i) { - double f1= key_info->actual_rec_per_key(i-1); - double f2= key_info->actual_rec_per_key(i); - table->cond_selectivity*= quick_cond_selectivity * f1 / f2; + table->cond_selectivity*= quick_cond_selectivity; + if (i != used_key_parts) + { + double f1= key_info->actual_rec_per_key(i-1); + double f2= key_info->actual_rec_per_key(i); + table->cond_selectivity*= f1 / f2; + } } } } } -end: - thd->mem_root= param.old_root; - free_root(&alloc, MYF(0)); DBUG_RETURN(FALSE); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b6e21a3b8a9..24d518d787a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6988,8 +6988,11 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, /* Discount the selectivity of the access method used to join table s */ if (s->quick && s->quick->index != MAX_KEY) { - /* A range scan by index s->quick->index is used to access table s */ - sel*= table->quick_rows[s->quick->index]/table_records; + if (!ref) + { + /* A range scan by index s->quick->index is used to access table s */ + sel*= table_records/table->quick_rows[s->quick->index]; + } } else if (ref) { From 4eb245f030da9ce1b4854e9129b08bc68aaef59f Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 20 Mar 2013 01:35:05 -0700 Subject: [PATCH 3/3] Correction for the previous fix. --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 24d518d787a..20010eb6465 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6988,7 +6988,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, /* Discount the selectivity of the access method used to join table s */ if (s->quick && s->quick->index != MAX_KEY) { - if (!ref) + if (join->positions[idx].key == 0) { /* A range scan by index s->quick->index is used to access table s */ sel*= table_records/table->quick_rows[s->quick->index];