summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc57
1 files changed, 32 insertions, 25 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 9f8f17eb4ba..31cb829fd93 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -9239,32 +9239,37 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
KEY *cur_index_info= table->key_info;
KEY *cur_index_info_end= cur_index_info + table->s->keys;
- KEY_PART_INFO *cur_part= NULL;
- KEY_PART_INFO *end_part; /* Last part for loops. */
- /* Last index part. */
- KEY_PART_INFO *last_part= NULL;
- KEY_PART_INFO *first_non_group_part= NULL;
- KEY_PART_INFO *first_non_infix_part= NULL;
- uint key_infix_parts= 0;
- uint cur_group_key_parts= 0;
- uint cur_group_prefix_len= 0;
/* Cost-related variables for the best index so far. */
double best_read_cost= DBL_MAX;
ha_rows best_records= 0;
SEL_ARG *best_index_tree= NULL;
ha_rows best_quick_prefix_records= 0;
uint best_param_idx= 0;
- double cur_read_cost= DBL_MAX;
- ha_rows cur_records;
+
+ const uint pk= param->table->s->primary_key;
SEL_ARG *cur_index_tree= NULL;
ha_rows cur_quick_prefix_records= 0;
uint cur_param_idx=MAX_KEY;
- key_map cur_used_key_parts;
- uint pk= param->table->s->primary_key;
for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
cur_index_info++, cur_index++)
{
+ KEY_PART_INFO *cur_part;
+ KEY_PART_INFO *end_part; /* Last part for loops. */
+ /* Last index part. */
+ KEY_PART_INFO *last_part;
+ KEY_PART_INFO *first_non_group_part;
+ KEY_PART_INFO *first_non_infix_part;
+ uint key_infix_parts;
+ uint cur_group_key_parts= 0;
+ uint cur_group_prefix_len= 0;
+ double cur_read_cost;
+ ha_rows cur_records;
+ key_map used_key_parts_map;
+ uint cur_key_infix_len= 0;
+ uchar cur_key_infix[MAX_KEY_LENGTH];
+ uint cur_used_key_parts;
+
/* Check (B1) - if current index is covering. */
if (!table->covering_keys.is_set(cur_index))
goto next_index;
@@ -9334,7 +9339,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
else if (join->select_distinct)
{
select_items_it.rewind();
- cur_used_key_parts.clear_all();
+ used_key_parts_map.clear_all();
uint max_key_part= 0;
while ((item= select_items_it++))
{
@@ -9345,13 +9350,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
Check if this attribute was already present in the select list.
If it was present, then its corresponding key part was alredy used.
*/
- if (cur_used_key_parts.is_set(key_part_nr))
+ if (used_key_parts_map.is_set(key_part_nr))
continue;
if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
goto next_index;
cur_part= cur_index_info->key_part + key_part_nr - 1;
cur_group_prefix_len+= cur_part->store_length;
- cur_used_key_parts.set_bit(key_part_nr);
+ used_key_parts_map.set_bit(key_part_nr);
++cur_group_key_parts;
max_key_part= max(max_key_part,key_part_nr);
}
@@ -9363,7 +9368,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
ulonglong all_parts, cur_parts;
all_parts= (1<<max_key_part) - 1;
- cur_parts= cur_used_key_parts.to_ulonglong() >> 1;
+ cur_parts= used_key_parts_map.to_ulonglong() >> 1;
if (all_parts != cur_parts)
goto next_index;
}
@@ -9413,7 +9418,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
&dummy);
if (!get_constant_key_infix(cur_index_info, index_range_tree,
first_non_group_part, min_max_arg_part,
- last_part, thd, key_infix, &key_infix_len,
+ last_part, thd, cur_key_infix,
+ &cur_key_infix_len,
&first_non_infix_part))
goto next_index;
}
@@ -9467,9 +9473,9 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
}
/* If we got to this point, cur_index_info passes the test. */
- key_infix_parts= key_infix_len ?
+ key_infix_parts= cur_key_infix_len ?
(first_non_infix_part - first_non_group_part) : 0;
- used_key_parts= cur_group_key_parts + key_infix_parts;
+ cur_used_key_parts= cur_group_key_parts + key_infix_parts;
/* Compute the cost of using this index. */
if (tree)
@@ -9481,7 +9487,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
cur_index_tree, TRUE);
}
- cost_group_min_max(table, cur_index_info, used_key_parts,
+ cost_group_min_max(table, cur_index_info, cur_used_key_parts,
cur_group_key_parts, tree, cur_index_tree,
cur_quick_prefix_records, have_min, have_max,
&cur_read_cost, &cur_records);
@@ -9492,7 +9498,6 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
{
- DBUG_ASSERT(tree != 0 || cur_param_idx == MAX_KEY);
index_info= cur_index_info;
index= cur_index;
best_read_cost= cur_read_cost;
@@ -9502,11 +9507,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
best_param_idx= cur_param_idx;
group_key_parts= cur_group_key_parts;
group_prefix_len= cur_group_prefix_len;
+ key_infix_len= cur_key_infix_len;
+ if (key_infix_len)
+ memcpy (key_infix, cur_key_infix, sizeof (key_infix));
+ used_key_parts= cur_used_key_parts;
}
- next_index:
- cur_group_key_parts= 0;
- cur_group_prefix_len= 0;
+ next_index:;
}
if (!index_info) /* No usable index found. */
DBUG_RETURN(NULL);