Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.6.18, 10.6.19, 10.6
-
None
Description
Discovered this in TODO-4919.
Check TODO-4919 for table DDL and imitation-stats.diff .
Consider a query (constants replaced)
explain
|
SELECT |
task0.sys_id
|
FROM |
task task0 ignore index(number) |
WHERE |
task0.sys_class_name = 'const' AND |
task0.assignment_group = 'uuid-const' AND |
task0.state IN (1,2,3) |
ORDER BY |
task0.number DESC limit 0,20 |
and two indexes:
-- assignment_group = 'uuid-const' matches 1% of the table
|
INDEX assignment_group(assignment_group) |
 |
-- sys_class_name = 'const' matches 50% of the table
|
INDEX sys_class_name_2(sys_class_name, number) |
Range optimizer produces range costs.
The costs originate from handler::multi_range_read_info_const() and
do include TIME_FOR_COMPARE:
cost->cpu_cost+= (rows2double(total_rows) / TIME_FOR_COMPARE +
|
MULTI_RANGE_READ_SETUP_COST);
|
Then, he code in best_access_path() calls
tmp= adjust_quick_cost(table->opt_range[key].cost,
|
table->opt_range[key].rows);
|
to remove TIME_FOR_COMPARE from quick select's cost before comparing
it with other costs. Makes sense.
Then, in get_range_limit_read_cost(), we take the quick select cost:
double best_cost= (double) table->opt_range[keynr].cost; |
and compare it with the cost we got from cost_for_index_read:
if (ref_rows > 0) |
{
|
double tmp= cost_for_index_read(tab->join->thd, table, keynr, |
ref_rows,
|
(ha_rows) tab->worst_seeks);
|
if (tmp < best_cost) |
Looking inside cost_for_index_read(), I see the cost is computed as follows:
cost= ((file->keyread_time(key, 0, records) +
|
file->read_time(key, 1, MY_MIN(records, worst_seeks))));
|
That is, it doesn't include TIME_FOR_COMPARE.
Should this be fixed?