Commit 4dc963a9 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #999251: Q13 from DBT3 uses table scan instead of covering index scan.

The optimizer chose a less efficient execution plan due to the following
defects of the code:
1. the generic handler function handler::keyread_time did not take into account
   that in clustered primary keys record data is included into each index entry
2. the function make_join_readinfo erroneously decided that index only scan
   could not be used if join cache was empoyed.

Added no additional test case.
Adjusted some of the test results.
parent c17bace4
......@@ -3221,7 +3221,7 @@ explain
select t1.a, count(t2.p) as count
from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort
1 SIMPLE t1 index NULL PRIMARY 4 NULL 8 Using index; Using temporary; Using filesort
1 SIMPLE t2 ref i_a i_a 5 test.t1.a 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
select t1.a, count(t2.p) as count
from t1 left join t2 on t1.a=t2.a and t2.p % 2 = 1 group by t1.a;
......@@ -4327,15 +4327,15 @@ SELECT t2.v FROM t1, t2, t3
WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL idx1 NULL NULL NULL 20 Using temporary; Using filesort
1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort
1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
SELECT t2.v FROM t1, t2, t3
WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
v
b
h
b
n
v
p
......@@ -4345,7 +4345,7 @@ SELECT t2.v FROM t1, t2, t3
WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL idx1 NULL NULL NULL 20 Using temporary; Using filesort
1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort
1 SIMPLE t3 hash_ALL PRIMARY,idx2 #hash#PRIMARY 4 test.t2.i 20 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t1 hash_ALL idx2 #hash#idx2 3 test.t3.v 45 Using where; Using join buffer (incremental, BNLH join)
SELECT t2.v FROM t1, t2, t3
......
......@@ -2365,8 +2365,8 @@ select_type SIMPLE
table t1
type index
possible_keys NULL
key PRIMARY
key_len 4
key b
key_len 10
ref NULL
rows 10
Extra Using index
......@@ -2652,7 +2652,7 @@ select_type SIMPLE
table t1
type index
possible_keys NULL
key PRIMARY
key b
key_len 8
ref NULL
rows 3
......
......@@ -2194,6 +2194,8 @@ double handler::keyread_time(uint index, uint ranges, ha_rows rows)
The model counts in the time to read index entries from cache.
*/
ulong len= table->key_info[index].key_length + ref_length;
if (index == table->s->primary_key && table->file->primary_key_is_clustered())
len= table->s->stored_rec_length;
double keys_per_block= (stats.block_size/2.0/len+1);
return (rows + keys_per_block-1)/ keys_per_block +
len*rows/(stats.block_size+1)/TIME_FOR_COMPARE ;
......
......@@ -10080,12 +10080,14 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
{
join->need_tmp= 1;
join->simple_order= join->simple_group= 0;
if (sort_by_tab->type == JT_NEXT)
if (sort_by_tab->type == JT_NEXT &&
!sort_by_tab->table->covering_keys.is_set(sort_by_tab->index))
{
sort_by_tab->type= JT_ALL;
sort_by_tab->read_first_record= join_init_read_record;
}
else if (sort_by_tab->type == JT_HASH_NEXT)
else if (sort_by_tab->type == JT_HASH_NEXT &&
!sort_by_tab->table->covering_keys.is_set(sort_by_tab->index))
{
sort_by_tab->type= JT_HASH;
sort_by_tab->read_first_record= join_init_read_record;
......
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