Commit 272e5e62 authored by Igor Babaev's avatar Igor Babaev

BNLH algorithm always used a full table scan over the joined table

even in the cases when there existed range/index-merge scans that
were cheaper than the full table scan.
This was a defect/bug of the implementation of mwl #128. 
Now hash join can work not only with full table scan of the joined
table, but also with full index scan, range and index-merge scans.
Accordingly, in the cases when hash join is used the column 'type'
in the EXPLAINs can contain now 'hash_ALL', 'hash_index', 'hash_range'
and 'hash_index_merge'. If hash join is coupled with a range/index_merge
scan then the columns 'key' and 'key_len' contain info not only on
the used hash index, but also on the indexes used for the scan.   
parent 6c7360b5
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 hash NULL hj_key 2 test.t1.id 3 Using where; Not exists; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 2 test.t1.id 3 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 2 test.t1.id 3 Using where; Not exists; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 2 test.t1.id 3 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 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)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 4 test.t1.a1 2 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t3 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1200 Using where; Not exists; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 test.t4.companynr 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 1 func 1199 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 hash NULL hj_key 4 test.t1.id1 1 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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
......@@ -2917,11 +2917,11 @@ a
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 Using where
1 SIMPLE t2 hash NULL hj_key 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_ALL NULL #hash#$hj 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 Using where
1 SIMPLE t1 hash NULL hj_key 5 test.t2.a 5 Using where; Using join buffer (flat, BNLH join)
1 SIMPLE t1 hash_ALL NULL #hash#$hj 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 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.t11.a 26 Using where; Using join buffer (incremental, BNLH join)
1 PRIMARY t21 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; Using join buffer (flat, BNLH join)
1 PRIMARY t22 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; Using join buffer (incremental, BNLH join)
2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
2 SUBQUERY t12 hash NULL hj_key 4 test.t11.a 8 Using where; Using join buffer (flat, BNLH join)
2 SUBQUERY t12 hash_ALL NULL #hash#$hj 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
......@@ -1155,7 +1155,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 hash NULL hj_key 5 test.E.a 10 Using where; End temporary; Using join buffer (incremental, BNLH join)
1 PRIMARY D hash_ALL NULL #hash#$hj 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(*)
......@@ -1193,11 +1193,11 @@ 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 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)
1 PRIMARY t1 hash_ALL NULL #hash#$hj 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 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)
1 PRIMARY t2 hash_ALL NULL #hash#$hj 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
......@@ -1212,7 +1212,7 @@ 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 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)
1 PRIMARY t1 hash_ALL NULL #hash#$hj 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,7 +138,7 @@ 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 hash NULL hj_key 5 test.it.a 32 Using where; Using join buffer (flat, BNLH join)
1 PRIMARY ot hash_ALL NULL #hash#$hj 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
......@@ -206,7 +206,7 @@ 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 hash NULL hj_key 5 test.it.a 52 Using where; Using join buffer (flat, BNLH join)
1 PRIMARY ot hash_ALL NULL #hash#$hj 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
......@@ -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 hash NULL hj_key 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH join)
1 PRIMARY t2 hash_ALL NULL #hash#$hj 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);
......
......@@ -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 hash PRIMARY PRIMARY 4 test.t1.pk 13 Using index; Using join buffer (flat, BNLH join)
1 SIMPLE t2 hash_range PRIMARY #hash#PRIMARY:PRIMARY 4:4 test.t1.pk 7 Using where; Using index; Using join buffer (flat, BNLH join)
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
pk
......
......@@ -146,6 +146,50 @@ SELECT City.Name, Country.Name, CountryLanguage.Language
CountryLanguage.Percentage > 50 AND
LENGTH(Language) < LENGTH(City.Name) - 2;
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND City.Population > 5000000
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND
(City.Population > 5000000 OR City.Name LIKE 'Za%')
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
CREATE INDEX City_Population ON City(Population);
CREATE INDEX City_Name ON City(Name);
ANALYZE TABLE City;
EXPLAIN
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND City.Population > 5000000
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND City.Population > 5000000
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
EXPLAIN
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND
(City.Population > 5000000 OR City.Name LIKE 'Za%')
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND
(City.Population > 5000000 OR City.Name LIKE 'Za%')
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
DROP INDEX City_Population ON City;
DROP INDEX City_Name ON City;
set join_cache_level=default;
set join_buffer_size=256;
......@@ -394,6 +438,34 @@ SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.P
Country.Population > 10000000;
EXPLAIN
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND City.Population > 5000000
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND City.Population > 5000000
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
CREATE INDEX City_Name ON City(Name);
EXPLAIN
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND
(City.Population > 5000000 OR City.Name LIKE 'Za%')
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
SELECT Country.Name, Country.Population, City.Name, City.Population
FROM Country LEFT JOIN City
ON City.Country=Country.Code AND
(City.Population > 5000000 OR City.Name LIKE 'Za%')
WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000;
DROP INDEX City_Name ON City;
show variables like 'join_buffer_size';
set join_cache_level=5;
show variables like 'join_cache_level';
......
This diff is collapsed.
......@@ -135,7 +135,7 @@ 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_HASH};
JT_HASH, JT_HASH_RANGE, JT_HASH_NEXT, JT_HASH_INDEX_MERGE};
class JOIN;
......
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