Commit 2b6509b7 authored by Igor Babaev's avatar Igor Babaev

The patch adds the code that allows to use equi-join conditions

for hash join in the cases when there are no suitable indexes
for these conditions.
parent 19a88d5e
This diff is collapsed.
This diff is collapsed.
......@@ -319,11 +319,11 @@ Lilliana Angelovska NULL NULL
explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 2 test.t1.id 3 Using where; Not exists; Using join buffer (flat, BNLH join)
explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.name is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 2 test.t1.id 3 Using where; Using join buffer (flat, BNLH join)
select count(*) from t1 left join t2 on (t1.id = t2.owner);
count(*)
4
......@@ -339,11 +339,11 @@ Lilliana Angelovska NULL NULL
explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 2 test.t1.id 3 Using where; Not exists; Using join buffer (flat, BNLH join)
explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.name is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 2 test.t1.id 3 Using where; Using join buffer (flat, BNLH join)
select count(*) from t2 right join t1 on (t1.id = t2.owner);
count(*)
4
......@@ -695,8 +695,8 @@ a1 a2 b1 b2 c1 c2
explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t2 hash NULL hj_key 4 test.t1.a1 2 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t3 hash NULL hj_key 5 test.t1.a1 2 Using where; Using join buffer (incremental, BNLH join)
drop table t1, t2, t3;
create table t1 (
a int(11),
......
......@@ -1370,7 +1370,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1200 Using where; Not exists; Using join buffer (flat, BNLH join)
select companynr,companyname from t2 left join t4 using (companynr) where companynr is null;
companynr companyname
select count(*) from t2 left join t4 using (companynr) where companynr is not null;
......@@ -1398,39 +1398,39 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
companynr companynr
37 36
......@@ -1438,7 +1438,7 @@ companynr companynr
explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 1 func 1199 Using where; Using join buffer (flat, BNLH join)
select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008;
fld1 companynr fld3 period
038008 37 reporters 1008
......@@ -2337,7 +2337,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found
1 SIMPLE t4 const id4 NULL NULL NULL 1
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 hash NULL hj_key 4 test.t1.id1 1 Using where; Using join buffer (flat, BNLH join)
select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3
left join t4 on id3 = id4 where id2 = 1 or id4 = 1;
id1 id2 id3 id4 id44
......@@ -2916,12 +2916,12 @@ a
4
EXPLAIN SELECT t1.a FROM t1 STRAIGHT_JOIN t2 ON t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
1 SIMPLE t2 hash NULL hj_key 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH join)
EXPLAIN SELECT t1.a FROM t1 INNER JOIN t2 ON t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 3
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where
1 SIMPLE t1 hash NULL hj_key 5 test.t2.a 5 Using where; Using join buffer (flat, BNLH join)
DROP TABLE t1,t2;
select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
......
......@@ -1031,10 +1031,10 @@ explain select t21.* from t21,t22 where t21.a = t22.a and
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY t21 hash NULL hj_key 4 test.t11.a 26 Using where; Using join buffer (flat, BNLH join)
1 PRIMARY t22 hash NULL hj_key 4 test.t21.a 26 Using where; Using join buffer (incremental, BNLH join)
2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
2 SUBQUERY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY t12 hash NULL hj_key 4 test.t11.a 8 Using where; Using join buffer (flat, BNLH join)
select t21.* from t21,t22 where t21.a = t22.a and
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
a b c
......@@ -1151,11 +1151,11 @@ set @@optimizer_switch='firstmatch=off,materialization=off';
set @@max_heap_table_size= 16384;
explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary
1 PRIMARY E ALL NULL NULL NULL NULL 5 Using where; Start temporary
1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join)
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join)
1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (incremental, BNL join)
1 PRIMARY D hash NULL hj_key 5 test.E.a 10 Using where; End temporary; Using join buffer (incremental, BNLH join)
flush status;
select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
count(*)
......@@ -1192,12 +1192,12 @@ insert into t3 select * from t1;
insert into t3 values (1),(2);
explain select * from t2 where a in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary
1 PRIMARY t1 hash NULL hj_key 4 test.t2.a 4 Using where; End temporary; Using join buffer (flat, BNLH join)
explain select * from t2 where a in (select a from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary
1 PRIMARY t2 hash NULL hj_key 5 test.t2.a 2 Using where; End temporary; Using join buffer (flat, BNLH join)
explain select * from t2 where a in (select a from t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
......@@ -1211,8 +1211,8 @@ create table t1 (a decimal);
insert into t1 values (1),(2);
explain select * from t1 where a in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Start temporary
1 PRIMARY t1 hash NULL hj_key 6 test.t1.a 2 Using where; End temporary; Using join buffer (flat, BNLH join)
drop table t1;
set @@optimizer_switch=@save_optimizer_switch;
create table t1 (a int);
......
......@@ -138,8 +138,8 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY it ALL NULL NULL NULL NULL 22
1 PRIMARY ot hash NULL hj_key 5 test.it.a 32 Using where; Using join buffer (flat, BNLH join)
2 SUBQUERY it ALL NULL NULL NULL NULL 22 Using where
select
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
......@@ -206,8 +206,8 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY it ALL NULL NULL NULL NULL 22
1 PRIMARY ot hash NULL hj_key 5 test.it.a 52 Using where; Using join buffer (flat, BNLH join)
2 SUBQUERY it ALL NULL NULL NULL NULL 22 Using where
select
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
......@@ -588,7 +588,7 @@ explain
select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t2 hash NULL hj_key 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH join)
2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY PRIMARY 4 func 1 Using index
drop table t0, t1, t2, t3;
create table t1 (a int);
......
set @save_optimizer_switch_jcl6=@@optimizer_switch;
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
set @@optimizer_switch='join_cache_hashed=off';
set join_cache_level=6;
show variables like 'join_cache_level';
Variable_name Value
......
......@@ -2656,7 +2656,7 @@ SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 11 Using where; Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash PRIMARY PRIMARY 4 test.t1.pk 13 Using index; Using join buffer (flat, BNLH join)
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
pk
......
......@@ -58,6 +58,60 @@ SELECT City.Name, Country.Name, CountryLanguage.Language
set join_cache_level=2;
show variables like 'join_cache_level';
EXPLAIN
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
EXPLAIN
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
set join_cache_level=3;
show variables like 'join_cache_level';
EXPLAIN
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
EXPLAIN
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
set join_cache_level=4;
show variables like 'join_cache_level';
EXPLAIN
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
......@@ -116,6 +170,60 @@ SELECT City.Name, Country.Name, CountryLanguage.Language
set join_cache_level=2;
show variables like 'join_cache_level';
EXPLAIN
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
EXPLAIN
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
set join_cache_level=3;
show variables like 'join_cache_level';
EXPLAIN
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
Country.Name LIKE 'L%' AND City.Population > 100000;
EXPLAIN
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
SELECT City.Name, Country.Name, CountryLanguage.Language
FROM City,Country,CountryLanguage
WHERE City.Country=Country.Code AND
CountryLanguage.Country=Country.Code AND
City.Name LIKE 'L%' AND Country.Population > 3000000 AND
CountryLanguage.Percentage > 50;
set join_cache_level=4;
show variables like 'join_cache_level';
EXPLAIN
SELECT City.Name, Country.Name FROM City,Country
WHERE City.Country=Country.Code AND
......@@ -2642,13 +2750,13 @@ SET SESSION optimizer_switch = 'outer_join_with_cache=on';
SET SESSION join_cache_level = 6;
EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0;
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0;
SET SESSION join_cache_level = 5;
EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0 ;
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0;
SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0;
SET SESSION optimizer_switch = 'outer_join_with_cache=off';
SET SESSION join_cache_level = DEFAULT;
......
......@@ -5,6 +5,7 @@
set @save_optimizer_switch_jcl6=@@optimizer_switch;
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
set @@optimizer_switch='join_cache_hashed=off';
set join_cache_level=6;
show variables like 'join_cache_level';
......
......@@ -1326,13 +1326,19 @@ static uint get_tmp_table_rec_length(List<Item> &items)
bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
{
KEYUSE *keyuse= table->reginfo.join_tab->keyuse;
uint key;
if (keyuse)
{
while (1) /* For each key */
{
key= keyuse->key;
if (keyuse->is_for_hash_join())
{
keyuse++;
if (keyuse->table != table)
return FALSE;
continue;
}
uint key= keyuse->key;
KEY *keyinfo= table->key_info + key;
key_part_map bound_parts= 0;
if (keyinfo->flags & HA_NOSAME)
......
......@@ -1052,9 +1052,8 @@ bool JOIN_CACHE::check_emb_key_usage()
CACHE_FIELD *copy;
CACHE_FIELD *copy_end;
uint len= 0;
TABLE *table= join_tab->table;
TABLE_REF *ref= &join_tab->ref;
KEY *keyinfo= table->key_info+ref->key;
KEY *keyinfo= join_tab->get_keyinfo_by_key_no(ref->key);
/*
If some of the key arguments are not from the local cache the key
......@@ -2520,7 +2519,7 @@ int JOIN_CACHE_HASHED::init()
pack_length+= get_size_of_rec_offset();
pack_length_with_blob_ptrs+= get_size_of_rec_offset();
ref_key_info= join_tab->table->key_info+join_tab->ref.key;
ref_key_info= join_tab->get_keyinfo_by_key_no(join_tab->ref.key);
ref_used_key_parts= join_tab->ref.key_parts;
hash_func= &JOIN_CACHE_HASHED::get_hash_idx_simple;
......@@ -3427,7 +3426,7 @@ uchar *JOIN_CACHE_BNLH::get_matching_chain_by_join_key()
uchar *key_ref_ptr;
TABLE *table= join_tab->table;
TABLE_REF *ref= &join_tab->ref;
KEY *keyinfo= table->key_info+ref->key;
KEY *keyinfo= join_tab->get_keyinfo_by_key_no(ref->key);
/* Build the join key value out of the record in the record buffer */
key_copy(key_buff, table->record[0], keyinfo, key_length, TRUE);
/* Look for this key in the join buffer */
......
This diff is collapsed.
......@@ -39,6 +39,11 @@
/* Values in optimize */
#define KEY_OPTIMIZE_EXISTS 1
#define KEY_OPTIMIZE_REF_OR_NULL 2
#define KEY_OPTIMIZE_EQ 4
inline uint get_hash_join_key_no() { return MAX_KEY; }
inline bool is_hash_join_key_no(uint key) { return key == MAX_KEY; }
typedef struct keyuse_t {
TABLE *table;
......@@ -68,6 +73,8 @@ typedef struct keyuse_t {
MAX_UINT Otherwise
*/
uint sj_pred_no;
bool is_for_hash_join() { return is_hash_join_key_no(key); }
} KEYUSE;
class store_key;
......@@ -127,7 +134,8 @@ typedef struct st_table_ref
*/
enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF,
JT_ALL, JT_RANGE, JT_NEXT, JT_FT, JT_REF_OR_NULL,
JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE};
JT_UNIQUE_SUBQUERY, JT_INDEX_SUBQUERY, JT_INDEX_MERGE,
JT_HASH};
class JOIN;
......@@ -159,6 +167,8 @@ typedef struct st_join_table {
st_join_table() {} /* Remove gcc warning */
TABLE *table;
KEYUSE *keyuse; /**< pointer to first used key */
KEY *hj_key; /**< descriptor of the used best hash join key
not supported by any index */
SQL_SELECT *select;
COND *select_cond;
COND *on_precond; /**< part of on condition to check before
......@@ -408,6 +418,11 @@ typedef struct st_join_table {
double get_partial_join_cardinality() { return partial_join_cardinality; }
bool hash_join_is_possible();
int make_scan_filter();
bool is_ref_for_hash_join() { return is_hash_join_key_no(ref.key); }
KEY *get_keyinfo_by_key_no(uint key)
{
return (is_hash_join_key_no(key) ? hj_key : table->key_info+key);
}
} JOIN_TAB;
......@@ -681,6 +696,15 @@ class JOIN :public Sql_alloc
Item *tmp_having; ///< To store having when processed temporary table
Item *having_history; ///< Store having for explain
ulonglong select_options;
/*
Bitmap of allowed types of the join caches that
can be used for join operations
*/
uint allowed_join_cache_types;
bool allowed_semijoin_with_cache;
bool allowed_outer_join_with_cache;
/* Maximum level of the join caches that can be used for join operations */
uint max_allowed_join_cache_level;
select_result *result;
TMP_TABLE_PARAM tmp_table_param;
MYSQL_LOCK *lock;
......@@ -947,6 +971,12 @@ class JOIN :public Sql_alloc
bool shrink_join_buffers(JOIN_TAB *jt,
ulonglong curr_space,
ulonglong needed_space);
void set_allowed_join_cache_types();
bool is_allowed_hash_join_access()
{
return test(allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) &&
max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
}
private:
/**
......
......@@ -2344,7 +2344,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
/* Allocate bitmaps */
bitmap_size= share->column_bitmap_size;
if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*4)))
if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*5)))
goto err;
bitmap_init(&outparam->def_read_set,
(my_bitmap_map*) bitmaps, share->fields, FALSE);
......@@ -2354,6 +2354,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
(my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE);
bitmap_init(&outparam->tmp_set,
(my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE);
bitmap_init(&outparam->eq_join_set,
(my_bitmap_map*) (bitmaps+bitmap_size*4), share->fields, FALSE);
outparam->default_column_bitmaps();
/* The table struct is now initialized; Open the table */
......@@ -5205,6 +5207,52 @@ bool TABLE::alloc_keys(uint key_count)
}
void TABLE::create_key_part_by_field(KEY *keyinfo,
KEY_PART_INFO *key_part_info,
Field *field)
{
field->flags|= PART_KEY_FLAG;
key_part_info->null_bit= field->null_bit;
key_part_info->null_offset= (uint) (field->null_ptr -
(uchar*) record[0]);
key_part_info->field= field;
key_part_info->offset= field->offset(record[0]);
key_part_info->length= (uint16) field->pack_length();
keyinfo->key_length+= key_part_info->length;
key_part_info->key_part_flag= 0;
/* TODO:
The below method of computing the key format length of the
key part is a copy/paste from opt_range.cc, and table.cc.
This should be factored out, e.g. as a method of Field.
In addition it is not clear if any of the Field::*_length
methods is supposed to compute the same length. If so, it
might be reused.
*/
key_part_info->store_length= key_part_info->length;
if (field->real_maybe_null())
{
key_part_info->store_length+= HA_KEY_NULL_LENGTH;
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
}
if (field->type() == MYSQL_TYPE_BLOB ||
field->real_type() == MYSQL_TYPE_VARCHAR)
{
key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
keyinfo->key_length+= HA_KEY_BLOB_LENGTH; // ???
key_part_info->key_part_flag|=
field->type() == MYSQL_TYPE_BLOB ? HA_BLOB_PART: HA_VAR_LENGTH_PART;
}
key_part_info->type= (uint8) field->key_type();
key_part_info->key_type =
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
0 : FIELDFLAG_BINARY;
}
/**
Add a key to a temporary table
......@@ -5255,54 +5303,18 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
if (!keyinfo->rec_per_key)
return TRUE;
bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
for (i= 0; i < key_parts; i++)
{
reg_field= field + next_field_no(arg);
if (key_start)
(*reg_field)->key_start.set_bit(key);
key_start= FALSE;
(*reg_field)->part_of_key.set_bit(key);
(*reg_field)->flags|= PART_KEY_FLAG;
key_part_info->null_bit= (*reg_field)->null_bit;
key_part_info->null_offset= (uint) ((*reg_field)->null_ptr -
(uchar*) record[0]);
key_part_info->field= *reg_field;
key_part_info->offset= (*reg_field)->offset(record[0]);
key_part_info->length= (uint16) (*reg_field)->pack_length();
keyinfo->key_length+= key_part_info->length;
key_part_info->key_part_flag= 0;
/* TODO:
The below method of computing the key format length of the
key part is a copy/paste from opt_range.cc, and table.cc.
This should be factored out, e.g. as a method of Field.
In addition it is not clear if any of the Field::*_length
methods is supposed to compute the same length. If so, it
might be reused.
*/
key_part_info->store_length= key_part_info->length;
if ((*reg_field)->real_maybe_null())
{
key_part_info->store_length+= HA_KEY_NULL_LENGTH;
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
if (unique)
keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
}
if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
(*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
{
key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
keyinfo->key_length+= HA_KEY_BLOB_LENGTH; // ???
}
key_part_info->type= (uint8) (*reg_field)->key_type();
key_part_info->key_type =
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
0 : FIELDFLAG_BINARY;
create_key_part_by_field(keyinfo, key_part_info, *reg_field);
key_start= FALSE;
key_part_info++;
}
set_if_bigger(s->max_key_length, keyinfo->key_length);
s->keys++;
return FALSE;
......
......@@ -725,6 +725,7 @@ struct st_table {
uchar *null_flags;
my_bitmap_map *bitmap_init_value;
MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set;
MY_BITMAP eq_join_set; /* used to mark equi-joined fields */
MY_BITMAP *read_set, *write_set, *vcol_set; /* Active column sets */
/*
The ID of the query that opened and is using this table. Has different
......@@ -955,6 +956,8 @@ struct st_table {
bool add_tmp_key(uint key, uint key_parts,
uint (*next_field_no) (uchar *), uchar *arg,
bool unique);
void create_key_part_by_field(KEY *keyinfo, KEY_PART_INFO *key_part_info,
Field *field);
bool is_children_attached(void);
inline void enable_keyread()
{
......
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