Commit 8ab81843 authored by Igor Babaev's avatar Igor Babaev

Fixed some bugs in the function that calculated the selectivity

of the table conditions. 
parent aab3c9fe
...@@ -3324,60 +3324,64 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) ...@@ -3324,60 +3324,64 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
table->cond_selectivity= 1.0; table->cond_selectivity= 1.0;
if (bitmap_is_clear_all(used_fields)) 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(&param, used_fields))
{ {
free_root(&alloc, MYF(0)); PARAM param;
DBUG_RETURN(FALSE); 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; if (create_key_parts_for_pseudo_indexes(&param, used_fields))
param.current_table= table->map; {
param.using_real_indexes= FALSE; free_root(&alloc, MYF(0));
param.real_keynr[0]= 0; DBUG_RETURN(FALSE);
param.alloced_sel_args= 0; }
thd->no_errors=1; // Don't warn about NULL 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;
SEL_TREE *tree; thd->no_errors=1; // Don't warn about NULL
SEL_ARG **key, **end;
uint idx= 0; SEL_TREE *tree;
SEL_ARG **key, **end;
uint idx= 0;
tree= get_mm_tree(&param, cond); tree= get_mm_tree(&param, cond);
if (!tree) if (!tree)
goto end; goto free_alloc;
for (key= tree->keys, end= key + param.keys; key != end; key++, idx++)
{
double rows;
if (*key)
{
rows= records_in_column_ranges(&param, idx, *key);
if (rows != HA_POS_ERROR)
(*key)->field->cond_selectivity= rows/table_records;
}
}
for (key= tree->keys, end= key + param.keys; key != end; key++, idx++) for (Field **field_ptr= table->field; *field_ptr; field_ptr++)
{
double rows;
if (*key)
{ {
rows= records_in_column_ranges(&param, idx, *key); Field *table_field= *field_ptr;
if (rows != HA_POS_ERROR) if (bitmap_is_set(table->read_set, table_field->field_index) &&
(*key)->field->cond_selectivity= rows/table_records; table_field->cond_selectivity < 1.0)
table->cond_selectivity*= table_field->cond_selectivity;
} }
}
for (Field **field_ptr= table->field; *field_ptr; field_ptr++) free_alloc:
{ thd->mem_root= param.old_root;
Field *table_field= *field_ptr; free_root(&alloc, MYF(0));
if (bitmap_is_set(table->read_set, table_field->field_index) &&
table_field->cond_selectivity < 1.0)
table->cond_selectivity*= table_field->cond_selectivity;
} }
/* Calculate the selectivity of the range conditions supported by indexes */ /* 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) ...@@ -3412,17 +3416,18 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
} }
if (i) if (i)
{ {
double f1= key_info->actual_rec_per_key(i-1); table->cond_selectivity*= quick_cond_selectivity;
double f2= key_info->actual_rec_per_key(i); if (i != used_key_parts)
table->cond_selectivity*= quick_cond_selectivity * f1 / f2; {
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); DBUG_RETURN(FALSE);
} }
......
...@@ -6988,8 +6988,11 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, ...@@ -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 */ /* Discount the selectivity of the access method used to join table s */
if (s->quick && s->quick->index != MAX_KEY) if (s->quick && s->quick->index != MAX_KEY)
{ {
/* A range scan by index s->quick->index is used to access table s */ if (!ref)
sel*= table->quick_rows[s->quick->index]/table_records; {
/* 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) else if (ref)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment