diff options
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 024bb9dd933..c2d46d62200 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4643,6 +4643,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, double roru_index_costs; ha_rows roru_total_records; double roru_intersect_part= 1.0; + size_t n_child_scans; DBUG_ENTER("get_best_disjunct_quick"); DBUG_PRINT("info", ("Full table scan cost: %g", read_time)); @@ -4659,7 +4660,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, } } - size_t n_child_scans= imerge->trees_next - imerge->trees; + n_child_scans= imerge->trees_next - imerge->trees; if (!n_child_scans) DBUG_RETURN(NULL); @@ -4877,8 +4878,8 @@ skip_to_ror_scan: (TIME_FOR_COMPARE_ROWID * M_LN2) + get_sweep_read_cost(param, roru_total_records); - DBUG_PRINT("info", ("ROR-union: cost %g, %d members", roru_total_cost, - n_child_scans)); + DBUG_PRINT("info", ("ROR-union: cost %g, %zu members", + roru_total_cost, n_child_scans)); TRP_ROR_UNION* roru; if (roru_total_cost < read_time) { @@ -8557,6 +8558,34 @@ bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param, } /* + Check whether the key parts inf_init..inf_end-1 of one index can compose + an infix for the key parts key_init..key_end-1 of another index +*/ + +static +bool is_key_infix(KEY_PART *key_init, KEY_PART *key_end, + KEY_PART *inf_init, KEY_PART *inf_end) +{ + KEY_PART *key_part, *inf_part; + for (key_part= key_init; key_part < key_end; key_part++) + { + if (key_part->field->eq(inf_init->field)) + break; + } + if (key_part == key_end) + return false; + for (key_part++, inf_part= inf_init + 1; + key_part < key_end && inf_part < inf_end; + key_part++, inf_part++) + { + if (!key_part->field->eq(inf_part->field)) + return false; + } + return inf_part == inf_end; +} + + +/* Check whether range parts of two trees must be ored for some indexes SYNOPSIS @@ -8612,14 +8641,9 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param, KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part; KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no; - KEY_PART *part1, *part2; - for (part1= key1_init, part2= key2_init; - part1 < key1_end && part2 < key2_end; - part1++, part2++) - { - if (!part1->field->eq(part2->field)) - DBUG_RETURN(FALSE); - } + if (!is_key_infix(key1_init, key1_end, key2_init, key2_end) && + !is_key_infix(key2_init, key2_end, key1_init, key1_end)) + DBUG_RETURN(FALSE); } } |