mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
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.
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user