mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -81,9 +81,9 @@ WHERE t3.a=1 OR t3.c IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 hash NULL hj_key 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
|
||||
FROM t2
|
||||
LEFT JOIN
|
||||
@ -157,10 +157,10 @@ WHERE t3.a>1 OR t3.c IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 hash NULL hj_key 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
|
||||
FROM t2
|
||||
LEFT JOIN
|
||||
@ -187,10 +187,10 @@ WHERE (t3.a>1 OR t3.c IS NULL) AND
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 hash NULL hj_key 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
|
||||
FROM t2
|
||||
LEFT JOIN
|
||||
@ -237,9 +237,9 @@ ON t7.b=t8.b AND t6.b < 10;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 hash NULL hj_key 5 test.t7.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`))) where 1
|
||||
Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`)) and (`test`.`t7`.`b` is not null))) where 1
|
||||
SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
|
||||
FROM (t6, t7)
|
||||
LEFT JOIN
|
||||
@ -551,16 +551,16 @@ t0.b=t1.b AND
|
||||
(t2.a >= 4 OR t2.c IS NULL);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t1 hash NULL hj_key 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 hash NULL hj_key 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
|
||||
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
|
||||
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
|
||||
FROM t0,t1
|
||||
@ -646,17 +646,17 @@ t0.b=t1.b AND
|
||||
(t9.a=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t1 hash NULL hj_key 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 hash NULL hj_key 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
SELECT t9.a,t9.b
|
||||
FROM t9;
|
||||
a b
|
||||
@ -845,9 +845,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 hash NULL hj_key 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) where (`test`.`t1`.`a` <= 2)
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) where (`test`.`t1`.`a` <= 2)
|
||||
CREATE INDEX idx_b ON t2(b);
|
||||
EXPLAIN EXTENDED
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
|
||||
@ -913,17 +913,17 @@ t0.b=t1.b AND
|
||||
(t9.a=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t1 hash NULL hj_key 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 hash NULL hj_key 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
CREATE INDEX idx_b ON t4(b);
|
||||
CREATE INDEX idx_b ON t5(b);
|
||||
EXPLAIN EXTENDED
|
||||
@ -963,17 +963,17 @@ t0.b=t1.b AND
|
||||
(t9.a=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t1 hash NULL hj_key 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
|
||||
1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
CREATE INDEX idx_b ON t8(b);
|
||||
EXPLAIN EXTENDED
|
||||
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
|
||||
@ -1012,17 +1012,17 @@ t0.b=t1.b AND
|
||||
(t9.a=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t1 hash NULL hj_key 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
|
||||
1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
CREATE INDEX idx_b ON t1(b);
|
||||
CREATE INDEX idx_a ON t0(a);
|
||||
EXPLAIN EXTENDED
|
||||
@ -1067,12 +1067,12 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
|
||||
1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t7 hash NULL hj_key 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
|
||||
1 SIMPLE t8 ref idx_b idx_b 5 test.t7.b 2 100.00 Using where; Using join buffer (incremental, BKA join)
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`)) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on((((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))) and (`test`.`t7`.`b` is not null)))) on((((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
|
||||
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
|
||||
FROM t0,t1
|
||||
@ -1324,7 +1324,7 @@ c11 c21 c31
|
||||
EXPLAIN SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t2 hash NULL hj_key 5 test.t1.c11 0 Using where; Using join buffer (flat, BNLH join)
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where; Using join buffer (incremental, BNL join)
|
||||
DROP TABLE t1,t2,t3;
|
||||
CREATE TABLE t1 (goods int(12) NOT NULL, price varchar(128) NOT NULL);
|
||||
|
@ -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);
|
||||
|
@ -1,6 +1,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';
|
||||
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 */
|
||||
|
@ -48,7 +48,7 @@
|
||||
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
|
||||
"MAYBE_REF","ALL","range","index","fulltext",
|
||||
"ref_or_null","unique_subquery","index_subquery",
|
||||
"index_merge"
|
||||
"index_merge","hash"
|
||||
};
|
||||
|
||||
struct st_sargable_param;
|
||||
@ -753,6 +753,8 @@ JOIN::optimize()
|
||||
|
||||
thd_proc_info(thd, "optimizing");
|
||||
|
||||
set_allowed_join_cache_types();
|
||||
|
||||
/* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */
|
||||
if (convert_join_subqueries_to_semijoins(this))
|
||||
DBUG_RETURN(1); /* purecov: inspected */
|
||||
@ -2985,7 +2987,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
||||
TODO. Apply single row substitution to null complemented inner tables
|
||||
for nested outer join operations.
|
||||
*/
|
||||
while (keyuse->table == table)
|
||||
while (keyuse->table == table && !keyuse->is_for_hash_join())
|
||||
{
|
||||
if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
|
||||
keyuse->val->is_null() && keyuse->null_rejecting)
|
||||
@ -3030,6 +3032,11 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
||||
s->type= JT_REF;
|
||||
while (keyuse->table == table)
|
||||
{
|
||||
if (keyuse->is_for_hash_join())
|
||||
{
|
||||
keyuse++;
|
||||
continue;
|
||||
}
|
||||
start_keyuse=keyuse;
|
||||
key=keyuse->key;
|
||||
s->keys.set_bit(key); // TODO: remove this ?
|
||||
@ -3493,21 +3500,27 @@ static uint get_semi_join_select_list_index(Field *field)
|
||||
*/
|
||||
|
||||
static void
|
||||
add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
add_key_field(JOIN *join,
|
||||
KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
Field *field, bool eq_func, Item **value, uint num_values,
|
||||
table_map usable_tables, SARGABLE_PARAM **sargables)
|
||||
{
|
||||
uint exists_optimize= 0;
|
||||
if (!(field->flags & PART_KEY_FLAG))
|
||||
uint optimize= 0;
|
||||
if (eq_func && join->is_allowed_hash_join_access() &&
|
||||
field->hash_join_is_possible())
|
||||
{
|
||||
optimize= KEY_OPTIMIZE_EQ;
|
||||
}
|
||||
if (!(field->flags & PART_KEY_FLAG) && !optimize)
|
||||
{
|
||||
// Don't remove column IS NULL on a LEFT JOIN table
|
||||
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
|
||||
!field->table->maybe_null || field->null_ptr)
|
||||
return; // Not a key. Skip it
|
||||
exists_optimize= KEY_OPTIMIZE_EXISTS;
|
||||
optimize= KEY_OPTIMIZE_EXISTS;
|
||||
DBUG_ASSERT(num_values == 1);
|
||||
}
|
||||
else
|
||||
if (optimize != KEY_OPTIMIZE_EXISTS)
|
||||
{
|
||||
table_map used_tables=0;
|
||||
bool optimizable=0;
|
||||
@ -3524,7 +3537,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
|
||||
!field->table->maybe_null || field->null_ptr)
|
||||
return; // Can't use left join optimize
|
||||
exists_optimize= KEY_OPTIMIZE_EXISTS;
|
||||
optimize= KEY_OPTIMIZE_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3544,6 +3557,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
Field BETWEEN ...
|
||||
Field IN ...
|
||||
*/
|
||||
if (field->flags & PART_KEY_FLAG)
|
||||
stat[0].key_dependent|=used_tables;
|
||||
|
||||
bool is_const=1;
|
||||
@ -3623,7 +3637,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
(*key_fields)->eq_func= eq_func;
|
||||
(*key_fields)->val= *value;
|
||||
(*key_fields)->level= and_level;
|
||||
(*key_fields)->optimize= exists_optimize;
|
||||
(*key_fields)->optimize= optimize;
|
||||
/*
|
||||
If the condition has form "tbl.keypart = othertbl.field" and
|
||||
othertbl.field can be NULL, there will be no matches if othertbl.field
|
||||
@ -3670,14 +3684,14 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
|
||||
*/
|
||||
|
||||
static void
|
||||
add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
|
||||
add_key_equal_fields(JOIN *join, KEY_FIELD **key_fields, uint and_level,
|
||||
Item_func *cond, Item_field *field_item,
|
||||
bool eq_func, Item **val,
|
||||
uint num_values, table_map usable_tables,
|
||||
SARGABLE_PARAM **sargables)
|
||||
{
|
||||
Field *field= field_item->field;
|
||||
add_key_field(key_fields, and_level, cond, field,
|
||||
add_key_field(join, key_fields, and_level, cond, field,
|
||||
eq_func, val, num_values, usable_tables, sargables);
|
||||
Item_equal *item_equal= field_item->item_equal;
|
||||
if (item_equal)
|
||||
@ -3692,7 +3706,7 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
|
||||
{
|
||||
if (!field->eq(item->field))
|
||||
{
|
||||
add_key_field(key_fields, and_level, cond, item->field,
|
||||
add_key_field(join, key_fields, and_level, cond, item->field,
|
||||
eq_func, val, num_values, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
@ -3825,7 +3839,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
values--;
|
||||
DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC ||
|
||||
cond_func->argument_count() != 2);
|
||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
add_key_equal_fields(join, key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->key_item()->real_item()),
|
||||
0, values,
|
||||
cond_func->argument_count()-1,
|
||||
@ -3840,7 +3854,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
if (is_local_field (cond_func->arguments()[i]))
|
||||
{
|
||||
field_item= (Item_field *) (cond_func->arguments()[i]->real_item());
|
||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
add_key_equal_fields(join, key_fields, *and_level, cond_func,
|
||||
field_item, 0, values, 1, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
@ -3855,7 +3869,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
|
||||
if (is_local_field (cond_func->arguments()[0]))
|
||||
{
|
||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
add_key_equal_fields(join, key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->arguments()[0])->real_item(),
|
||||
equal_func,
|
||||
cond_func->arguments()+1, 1, usable_tables,
|
||||
@ -3864,7 +3878,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
if (is_local_field (cond_func->arguments()[1]) &&
|
||||
cond_func->functype() != Item_func::LIKE_FUNC)
|
||||
{
|
||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
add_key_equal_fields(join, key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->arguments()[1])->real_item(),
|
||||
equal_func,
|
||||
cond_func->arguments(),1,usable_tables,
|
||||
@ -3880,7 +3894,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
Item *tmp=new Item_null;
|
||||
if (unlikely(!tmp)) // Should never be true
|
||||
return;
|
||||
add_key_equal_fields(key_fields, *and_level, cond_func,
|
||||
add_key_equal_fields(join, key_fields, *and_level, cond_func,
|
||||
(Item_field*) (cond_func->arguments()[0])->real_item(),
|
||||
cond_func->functype() == Item_func::ISNULL_FUNC,
|
||||
&tmp, 1, usable_tables, sargables);
|
||||
@ -3900,7 +3914,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
*/
|
||||
while ((item= it++))
|
||||
{
|
||||
add_key_field(key_fields, *and_level, cond_func, item->field,
|
||||
add_key_field(join, key_fields, *and_level, cond_func, item->field,
|
||||
TRUE, &const_item, 1, usable_tables, sargables);
|
||||
}
|
||||
}
|
||||
@ -3921,7 +3935,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
|
||||
if (!field->eq(item->field))
|
||||
{
|
||||
Item *tmp_item= item;
|
||||
add_key_field(key_fields, *and_level, cond_func, field,
|
||||
add_key_field(join, key_fields, *and_level, cond_func, field,
|
||||
TRUE, &tmp_item, 1, usable_tables,
|
||||
sargables);
|
||||
}
|
||||
@ -3942,6 +3956,58 @@ max_part_bit(key_part_map bits)
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Add a new keuse to the specified array of KEYUSE objects
|
||||
|
||||
@param[in,out] keyuse_array array of keyuses to be extended
|
||||
@param[in] key_field info on the key use occurrence
|
||||
@param[in] key key number for the keyse to be added
|
||||
@param[in] part key part for the keyuse to be added
|
||||
|
||||
@note
|
||||
The function builds a new KEYUSE object for a key use utilizing the info
|
||||
on the left anf right parts of the given key use extracted from the
|
||||
structure key_field, the key number and key part for this key use.
|
||||
The built object is added to the dynamic array keyuse_array.
|
||||
|
||||
@retval 0 the built object is succesfully added
|
||||
@retval 1 otherwise
|
||||
*/
|
||||
|
||||
static bool
|
||||
add_keyuse(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field,
|
||||
uint key, uint part)
|
||||
{
|
||||
KEYUSE keyuse;
|
||||
Field *field= key_field->field;
|
||||
|
||||
keyuse.table= field->table;
|
||||
keyuse.val= key_field->val;
|
||||
keyuse.key= key;
|
||||
if (!is_hash_join_key_no(key))
|
||||
{
|
||||
keyuse.keypart=part;
|
||||
keyuse.keypart_map= (key_part_map) 1 << part;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
If this is a key use for hash join then keypart of
|
||||
the added element actually contains the field number.
|
||||
*/
|
||||
keyuse.keypart= field->field_index;
|
||||
keyuse.keypart_map= (key_part_map) 0;
|
||||
}
|
||||
keyuse.used_tables= key_field->val->used_tables();
|
||||
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
|
||||
keyuse.null_rejecting= key_field->null_rejecting;
|
||||
keyuse.cond_guard= key_field->cond_guard;
|
||||
keyuse.sj_pred_no= key_field->sj_pred_no;
|
||||
return (insert_dynamic(keyuse_array,(uchar*) &keyuse));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Add all keys with uses 'field' for some keypart
|
||||
If field->and_level != and_level then only mark key_part as const_part
|
||||
@ -3952,11 +4018,10 @@ max_part_bit(key_part_map bits)
|
||||
*/
|
||||
|
||||
static bool
|
||||
add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
|
||||
add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
|
||||
{
|
||||
Field *field=key_field->field;
|
||||
TABLE *form= field->table;
|
||||
KEYUSE keyuse;
|
||||
|
||||
if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
|
||||
{
|
||||
@ -3972,22 +4037,24 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
|
||||
{
|
||||
if (field->eq(form->key_info[key].key_part[part].field))
|
||||
{
|
||||
keyuse.table= field->table;
|
||||
keyuse.val = key_field->val;
|
||||
keyuse.key = key;
|
||||
keyuse.keypart=part;
|
||||
keyuse.keypart_map= (key_part_map) 1 << part;
|
||||
keyuse.used_tables=key_field->val->used_tables();
|
||||
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
|
||||
keyuse.ref_table_rows= 0;
|
||||
keyuse.null_rejecting= key_field->null_rejecting;
|
||||
keyuse.cond_guard= key_field->cond_guard;
|
||||
keyuse.sj_pred_no= key_field->sj_pred_no;
|
||||
if (insert_dynamic(keyuse_array,(uchar*) &keyuse))
|
||||
if (add_keyuse(keyuse_array, key_field, key, part))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (field->hash_join_is_possible() &&
|
||||
(key_field->optimize & KEY_OPTIMIZE_EQ) &&
|
||||
key_field->val->used_tables())
|
||||
{
|
||||
/*
|
||||
If a key use is extracted from an equi-join predicate then it is
|
||||
added not only as a key use for every index whose component can
|
||||
be evalusted utilizing this key use, but also as a key use for
|
||||
hash join. Such key uses are marked with a special key number.
|
||||
*/
|
||||
if (add_keyuse(keyuse_array, key_field, get_hash_join_key_no(), 0))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@ -4300,6 +4367,18 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
|
||||
found_eq_constant=0;
|
||||
for (i=0 ; i < keyuse->elements-1 ; i++,use++)
|
||||
{
|
||||
if (use->is_for_hash_join())
|
||||
{
|
||||
if (!use->table->reginfo.join_tab->keyuse)
|
||||
use->table->reginfo.join_tab->keyuse= save_pos;
|
||||
#ifdef HAVE_valgrind
|
||||
/* Valgrind complains about overlapped memcpy when save_pos==use. */
|
||||
if (save_pos != use)
|
||||
#endif
|
||||
*save_pos= *use;
|
||||
save_pos++;
|
||||
continue;
|
||||
}
|
||||
if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
|
||||
use->table->const_key_parts[use->key]|= use->keypart_map;
|
||||
if (use->keypart != FT_KEYPART)
|
||||
@ -4518,16 +4597,21 @@ best_access_path(JOIN *join,
|
||||
double tmp;
|
||||
ha_rows rec;
|
||||
bool best_uses_jbuf= FALSE;
|
||||
MY_BITMAP *eq_join_set= &s->table->eq_join_set;
|
||||
KEYUSE *start_key=0;
|
||||
KEYUSE *hj_start_key= 0;
|
||||
|
||||
Loose_scan_opt loose_scan_opt;
|
||||
DBUG_ENTER("best_access_path");
|
||||
|
||||
bitmap_clear_all(eq_join_set);
|
||||
|
||||
loose_scan_opt.init(join, s, remaining_tables);
|
||||
|
||||
if (s->keyuse)
|
||||
{ /* Use key if possible */
|
||||
TABLE *table= s->table;
|
||||
KEYUSE *keyuse,*start_key=0;
|
||||
KEYUSE *keyuse;
|
||||
double best_records= DBL_MAX;
|
||||
uint max_key_part=0;
|
||||
|
||||
@ -4535,15 +4619,29 @@ best_access_path(JOIN *join,
|
||||
rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
|
||||
for (keyuse=s->keyuse ; keyuse->table == table ;)
|
||||
{
|
||||
KEY *keyinfo;
|
||||
key_part_map found_part= 0;
|
||||
table_map found_ref= 0;
|
||||
uint key= keyuse->key;
|
||||
KEY *keyinfo= table->key_info+key;
|
||||
bool ft_key= (keyuse->keypart == FT_KEYPART);
|
||||
/* Bitmap of keyparts where the ref access is over 'keypart=const': */
|
||||
key_part_map const_part= 0;
|
||||
/* The or-null keypart in ref-or-null access: */
|
||||
key_part_map ref_or_null_part= 0;
|
||||
if (is_hash_join_key_no(key))
|
||||
{
|
||||
if (!(remaining_tables & keyuse->used_tables) &&
|
||||
idx > join->const_tables)
|
||||
{
|
||||
if (!hj_start_key)
|
||||
hj_start_key= keyuse;
|
||||
bitmap_set_bit(eq_join_set, keyuse->keypart);
|
||||
}
|
||||
keyuse++;
|
||||
continue;
|
||||
}
|
||||
|
||||
keyinfo= table->key_info+key;
|
||||
|
||||
/* Calculate how many key segments of the current key we can use */
|
||||
start_key= keyuse;
|
||||
@ -4884,6 +4982,41 @@ best_access_path(JOIN *join,
|
||||
records= best_records;
|
||||
}
|
||||
|
||||
/*
|
||||
If there is no key to access the table, but there is an equi-join
|
||||
predicate connecting the table with the privious tables then we
|
||||
consider the possibility of using hash join.
|
||||
*/
|
||||
if (idx >= join->const_tables && best_key == 0 &&
|
||||
!bitmap_is_clear_all(eq_join_set) && !disable_jbuf &&
|
||||
(!s->emb_sj_nest ||
|
||||
join->allowed_semijoin_with_cache) &&
|
||||
(!(s->table->map & join->outer_join) ||
|
||||
join->allowed_outer_join_with_cache))
|
||||
{
|
||||
double join_sel= 0.1;
|
||||
/* Estimate the cost of the hash join access to the table */
|
||||
ha_rows rnd_records= s->found_records;
|
||||
if (found_constraint)
|
||||
rnd_records-= rnd_records/4;
|
||||
if (s->table->quick_condition_rows != s->found_records)
|
||||
rnd_records= s->table->quick_condition_rows;
|
||||
|
||||
tmp= s->table->file->scan_time();
|
||||
/* We read the table as many times as join buffer becomes full. */
|
||||
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
|
||||
record_count /
|
||||
(double) thd->variables.join_buff_size));
|
||||
tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
|
||||
best_time= tmp +
|
||||
(record_count*join_sel) / TIME_FOR_COMPARE * rnd_records;
|
||||
best= tmp;
|
||||
records= rows2double(rnd_records);
|
||||
best_key= hj_start_key;
|
||||
best_ref_depends_map= 0;
|
||||
best_uses_jbuf= test(!disable_jbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
Don't test table scan if it can't be better.
|
||||
Prefer key lookup if we would use the same key for scanning.
|
||||
@ -5001,7 +5134,8 @@ best_access_path(JOIN *join,
|
||||
*/
|
||||
if (best == DBL_MAX ||
|
||||
(tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
|
||||
best + record_count/(double) TIME_FOR_COMPARE*records))
|
||||
(best_key->is_for_hash_join() ? best_time :
|
||||
best + record_count/(double) TIME_FOR_COMPARE*records)))
|
||||
{
|
||||
/*
|
||||
If the table has a range (s->quick is set) make_join_select()
|
||||
@ -5770,7 +5904,7 @@ best_extension_by_limited_search(JOIN *join,
|
||||
if (best_record_count >= current_record_count &&
|
||||
best_read_time >= current_read_time &&
|
||||
/* TODO: What is the reasoning behind this condition? */
|
||||
(!(s->key_dependent & remaining_tables) ||
|
||||
(!(s->key_dependent & allowed_tables & remaining_tables) ||
|
||||
join->positions[idx].records_read < 2.0))
|
||||
{
|
||||
best_record_count= current_record_count;
|
||||
@ -5980,39 +6114,6 @@ void JOIN_TAB::calc_used_field_length(bool max_fl)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Check whether hash join algorithm can be used to join this table
|
||||
|
||||
@details
|
||||
This function finds out whether the ref items that have been chosen
|
||||
by the planner to access this table can be used for hash join algorithms.
|
||||
The answer depends on a certain property of the the fields of the
|
||||
joined tables on which the hash join key is built. If hash join is
|
||||
allowed for all these fields the answer is positive.
|
||||
|
||||
@note
|
||||
The function is supposed to be called now only after the function
|
||||
get_best_combination has been called.
|
||||
|
||||
@retval TRUE it's possible to use hash join to join this table
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
|
||||
bool JOIN_TAB::hash_join_is_possible()
|
||||
{
|
||||
if (type != JT_REF && type != JT_EQ_REF)
|
||||
return FALSE;
|
||||
KEY *keyinfo= &table->key_info[ref.key];
|
||||
for (uint i= 0; i < ref.key_parts; i++)
|
||||
{
|
||||
if (!keyinfo->key_part[i].field->hash_join_is_possible())
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@brief
|
||||
Extract pushdown conditions for a table scan
|
||||
@ -6053,6 +6154,37 @@ int JOIN_TAB::make_scan_filter()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Check whether hash join algorithm can be used to join this table
|
||||
|
||||
@details
|
||||
This function finds out whether the ref items that have been chosen
|
||||
by the planner to access this table can be used for hash join algorithms.
|
||||
The answer depends on a certain property of the the fields of the
|
||||
joined tables on which the hash join key is built.
|
||||
|
||||
@note
|
||||
At present the function is supposed to be called only after the function
|
||||
get_best_combination has been called.
|
||||
|
||||
@retval TRUE it's possible to use hash join to join this table
|
||||
@retval FALSE otherwise
|
||||
*/
|
||||
|
||||
bool JOIN_TAB::hash_join_is_possible()
|
||||
{
|
||||
if (type != JT_REF && type != JT_EQ_REF)
|
||||
return FALSE;
|
||||
if (!is_ref_for_hash_join())
|
||||
{
|
||||
KEY *keyinfo= table->key_info + ref.key;
|
||||
return keyinfo->key_part[0].field->hash_join_is_possible();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static uint
|
||||
cache_record_length(JOIN *join,uint idx)
|
||||
{
|
||||
@ -6216,7 +6348,7 @@ get_best_combination(JOIN *join)
|
||||
|
||||
if (j->type == JT_SYSTEM)
|
||||
continue;
|
||||
if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key) ||
|
||||
if ( !(keyuse= join->best_positions[tablenr].key) ||
|
||||
(join->best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN))
|
||||
{
|
||||
j->type=JT_ALL;
|
||||
@ -6234,22 +6366,108 @@ get_best_combination(JOIN *join)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
Create a descriptor of hash join key to access a given join table
|
||||
|
||||
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
table_map used_tables)
|
||||
@param join join which the join table belongs to
|
||||
@param join_tab the join table to access
|
||||
@param org_keyuse beginning of the key uses to join this table
|
||||
@param used_tables bitmap of the previous tables
|
||||
|
||||
@details
|
||||
This function first finds key uses that can be utilized by the hash join
|
||||
algorithm to join join_tab to the previous tables marked in the bitmap
|
||||
used_tables. The tested key uses are taken from the array of all key uses
|
||||
for 'join' starting from the position org_keyuse. After all interesting key
|
||||
uses have been found the function builds a descriptor of the corresponding
|
||||
key that is used by the hash join algorithm would it be chosen to join
|
||||
the table join_tab.
|
||||
|
||||
@retval FALSE the descriptor for a hash join key is successfully created
|
||||
@retval TRUE otherwise
|
||||
*/
|
||||
|
||||
static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
|
||||
KEYUSE *org_keyuse, table_map used_tables)
|
||||
{
|
||||
KEYUSE *keyuse=org_keyuse;
|
||||
bool ftkey=(keyuse->keypart == FT_KEYPART);
|
||||
KEY *keyinfo;
|
||||
KEY_PART_INFO *key_part_info;
|
||||
KEYUSE *keyuse= org_keyuse;
|
||||
uint key_parts= 0;
|
||||
THD *thd= join->thd;
|
||||
uint keyparts,length,key;
|
||||
TABLE *table= join_tab->table;
|
||||
bool first_keyuse= TRUE;
|
||||
DBUG_ENTER("create_hj_key_for_table");
|
||||
|
||||
do
|
||||
{
|
||||
if (!(~used_tables & keyuse->used_tables) &&
|
||||
(first_keyuse || keyuse->keypart != (keyuse-1)->keypart))
|
||||
key_parts++;
|
||||
first_keyuse= FALSE;
|
||||
keyuse++;
|
||||
} while (keyuse->table == table && keyuse->is_for_hash_join());
|
||||
if (!key_parts)
|
||||
DBUG_RETURN(TRUE);
|
||||
if (!(keyinfo= (KEY *) thd->alloc(sizeof(KEY))) ||
|
||||
!(key_part_info = (KEY_PART_INFO *) thd->alloc(sizeof(KEY_PART_INFO)*
|
||||
key_parts)))
|
||||
DBUG_RETURN(TRUE);
|
||||
keyinfo->usable_key_parts= keyinfo->key_parts = key_parts;
|
||||
keyinfo->key_part= key_part_info;
|
||||
keyinfo->key_length=0;
|
||||
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
||||
keyinfo->flags= HA_GENERATED_KEY;
|
||||
keyinfo->name= (char *) "hj_key";
|
||||
keyinfo->rec_per_key= (ulong*) thd->alloc(sizeof(ulong)*key_parts);
|
||||
if (!keyinfo->rec_per_key)
|
||||
DBUG_RETURN(TRUE);
|
||||
bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
|
||||
keyinfo->key_part= key_part_info;
|
||||
|
||||
first_keyuse= TRUE;
|
||||
keyuse= org_keyuse;
|
||||
do
|
||||
{
|
||||
if (!(~used_tables & keyuse->used_tables) &&
|
||||
(first_keyuse || keyuse->keypart != (keyuse-1)->keypart))
|
||||
{
|
||||
Field *field= table->field[keyuse->keypart];
|
||||
table->create_key_part_by_field(keyinfo, key_part_info, field);
|
||||
first_keyuse= FALSE;
|
||||
key_part_info++;
|
||||
}
|
||||
keyuse++;
|
||||
} while (keyuse->table == table && keyuse->is_for_hash_join());
|
||||
|
||||
join_tab->hj_key= keyinfo;
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
|
||||
KEYUSE *org_keyuse, table_map used_tables)
|
||||
{
|
||||
uint keyparts, length, key;
|
||||
TABLE *table;
|
||||
KEY *keyinfo;
|
||||
KEYUSE *keyuse= org_keyuse;
|
||||
bool ftkey= (keyuse->keypart == FT_KEYPART);
|
||||
THD *thd= join->thd;
|
||||
DBUG_ENTER("create_ref_for_key");
|
||||
|
||||
/* Use best key from find_best */
|
||||
table=j->table;
|
||||
key=keyuse->key;
|
||||
keyinfo=table->key_info+key;
|
||||
table= j->table;
|
||||
key= keyuse->key;
|
||||
if (!is_hash_join_key_no(key))
|
||||
keyinfo= table->key_info+key;
|
||||
else
|
||||
{
|
||||
if (create_hj_key_for_table(join, j, org_keyuse, used_tables))
|
||||
DBUG_RETURN(TRUE);
|
||||
keyinfo= j->hj_key;
|
||||
}
|
||||
|
||||
if (ftkey)
|
||||
{
|
||||
@ -6272,12 +6490,18 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
{
|
||||
if (!(~used_tables & keyuse->used_tables))
|
||||
{
|
||||
if (keyparts == keyuse->keypart &&
|
||||
if (is_hash_join_key_no(key) &&
|
||||
(keyparts == 0 || keyuse->keypart != (keyuse-1)->keypart))
|
||||
{
|
||||
length+= keyinfo->key_part[keyparts].store_length;
|
||||
keyparts++;
|
||||
}
|
||||
else if (!is_hash_join_key_no(key) && keyparts == keyuse->keypart &&
|
||||
!(found_part_ref_or_null & keyuse->optimize))
|
||||
{
|
||||
keyparts++;
|
||||
length+= keyinfo->key_part[keyuse->keypart].store_length;
|
||||
found_part_ref_or_null|= keyuse->optimize;
|
||||
keyparts++;
|
||||
}
|
||||
}
|
||||
keyuse++;
|
||||
@ -6285,14 +6509,13 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
} /* not ftkey */
|
||||
|
||||
/* set up fieldref */
|
||||
keyinfo=table->key_info+key;
|
||||
j->ref.key_parts=keyparts;
|
||||
j->ref.key_length=length;
|
||||
j->ref.key=(int) key;
|
||||
j->ref.key_parts= keyparts;
|
||||
j->ref.key_length= length;
|
||||
j->ref.key= (int) key;
|
||||
if (!(j->ref.key_buff= (uchar*) thd->calloc(ALIGN_SIZE(length)*2)) ||
|
||||
!(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
|
||||
(keyparts+1)))) ||
|
||||
!(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
|
||||
!(j->ref.items=(Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
|
||||
!(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
@ -6322,8 +6545,10 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
uint i;
|
||||
for (i=0 ; i < keyparts ; keyuse++,i++)
|
||||
{
|
||||
while (keyuse->keypart != i ||
|
||||
((~used_tables) & keyuse->used_tables))
|
||||
while (((~used_tables) & keyuse->used_tables) ||
|
||||
(keyuse->keypart !=
|
||||
(is_hash_join_key_no(key) ?
|
||||
keyinfo->key_part[i].field->field_index : i)))
|
||||
keyuse++; /* Skip other parts */
|
||||
|
||||
uint maybe_null= test(keyinfo->key_part[i].null_bit);
|
||||
@ -6335,10 +6560,12 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
if (!keyuse->used_tables &&
|
||||
!(join->select_options & SELECT_DESCRIBE))
|
||||
{ // Compare against constant
|
||||
store_key_item tmp(thd, keyinfo->key_part[i].field,
|
||||
store_key_item tmp(thd,
|
||||
keyinfo->key_part[i].field,
|
||||
key_buff + maybe_null,
|
||||
maybe_null ? key_buff : 0,
|
||||
keyinfo->key_part[i].length, keyuse->val,
|
||||
keyinfo->key_part[i].length,
|
||||
keyuse->val,
|
||||
FALSE);
|
||||
if (thd->is_fatal_error)
|
||||
DBUG_RETURN(TRUE);
|
||||
@ -6356,7 +6583,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
|
||||
*/
|
||||
if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
|
||||
null_ref_key= key_buff;
|
||||
key_buff+=keyinfo->key_part[i].store_length;
|
||||
key_buff+= keyinfo->key_part[i].store_length;
|
||||
}
|
||||
} /* not ftkey */
|
||||
*ref_key=0; // end_marker
|
||||
@ -7331,6 +7558,12 @@ void set_join_cache_denial(JOIN_TAB *join_tab)
|
||||
don't do join buffering for the first table in sjm nest.
|
||||
*/
|
||||
join_tab[-1].next_select= sub_select;
|
||||
if (join_tab->type == JT_REF && join_tab->is_ref_for_hash_join())
|
||||
{
|
||||
join_tab->type= JT_ALL;
|
||||
join_tab->ref.key_parts= 0;
|
||||
join_tab->join->return_tab= join_tab;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7649,15 +7882,17 @@ uint check_join_cache_usage(JOIN_TAB *tab,
|
||||
ha_rows rows;
|
||||
uint bufsz= 4096;
|
||||
JOIN_CACHE *prev_cache=0;
|
||||
uint cache_level= join->thd->variables.join_cache_level;
|
||||
uint cache_level= join->max_allowed_join_cache_level;
|
||||
bool force_unlinked_cache=
|
||||
!optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL);
|
||||
!(join->allowed_join_cache_types & JOIN_CACHE_INCREMENTAL_BIT);
|
||||
bool no_hashed_cache=
|
||||
!optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_HASHED);
|
||||
!(join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT);
|
||||
bool no_bka_cache=
|
||||
!optimizer_flag(join->thd, OPTIMIZER_SWITCH_JOIN_CACHE_BKA);
|
||||
!(join->allowed_join_cache_types & JOIN_CACHE_BKA_BIT);
|
||||
uint i= tab - join->join_tab;
|
||||
|
||||
join->return_tab= 0;
|
||||
|
||||
*icp_other_tables_ok= TRUE;
|
||||
*idx_cond_fact_out= TRUE;
|
||||
if (cache_level == 0 || i == join->const_tables || !prev_tab)
|
||||
@ -7676,10 +7911,10 @@ uint check_join_cache_usage(JOIN_TAB *tab,
|
||||
goto no_join_cache;
|
||||
|
||||
if (tab->is_inner_table_of_semi_join_with_first_match() &&
|
||||
!optimizer_flag(join->thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE))
|
||||
!join->allowed_semijoin_with_cache)
|
||||
goto no_join_cache;
|
||||
if (tab->is_inner_table_of_outer_join() &&
|
||||
!optimizer_flag(join->thd, OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE))
|
||||
!join->allowed_outer_join_with_cache)
|
||||
goto no_join_cache;
|
||||
|
||||
/*
|
||||
@ -7731,7 +7966,6 @@ uint check_join_cache_usage(JOIN_TAB *tab,
|
||||
goto no_join_cache;
|
||||
}
|
||||
|
||||
if (!force_unlinked_cache)
|
||||
prev_cache= prev_tab->cache;
|
||||
|
||||
switch (tab->type) {
|
||||
@ -7751,25 +7985,25 @@ uint check_join_cache_usage(JOIN_TAB *tab,
|
||||
case JT_EQ_REF:
|
||||
if (cache_level <=2 || (no_hashed_cache && no_bka_cache))
|
||||
goto no_join_cache;
|
||||
if (!tab->is_ref_for_hash_join())
|
||||
{
|
||||
flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
|
||||
if (tab->table->covering_keys.is_set(tab->ref.key))
|
||||
flags|= HA_MRR_INDEX_ONLY;
|
||||
rows= tab->table->file->multi_range_read_info(tab->ref.key, 10, 20,
|
||||
tab->ref.key_parts,
|
||||
&bufsz, &flags, &cost);
|
||||
}
|
||||
|
||||
if ((cache_level <=4 && !no_hashed_cache) || no_bka_cache ||
|
||||
((flags & HA_MRR_NO_ASSOCIATION) && cache_level <=6))
|
||||
((flags & HA_MRR_NO_ASSOCIATION) && cache_level <=6) ||
|
||||
tab->is_ref_for_hash_join())
|
||||
{
|
||||
if (!tab->hash_join_is_possible() ||
|
||||
tab->make_scan_filter())
|
||||
goto no_join_cache;
|
||||
if (cache_level == 3)
|
||||
{
|
||||
if (prev_tab->cache)
|
||||
goto no_join_cache;
|
||||
prev_cache= 0;
|
||||
}
|
||||
if ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
|
||||
((options & SELECT_DESCRIBE) || !tab->cache->init()))
|
||||
{
|
||||
@ -7814,6 +8048,8 @@ uint check_join_cache_usage(JOIN_TAB *tab,
|
||||
}
|
||||
|
||||
no_join_cache:
|
||||
if (tab->type != JT_ALL && tab->is_ref_for_hash_join())
|
||||
tab->type= JT_ALL;
|
||||
revise_cache_usage(tab);
|
||||
return 0;
|
||||
}
|
||||
@ -7845,12 +8081,16 @@ static bool
|
||||
make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
|
||||
{
|
||||
uint i;
|
||||
|
||||
DBUG_ENTER("make_join_readinfo");
|
||||
|
||||
restart:
|
||||
|
||||
uint jcl= 0;
|
||||
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
|
||||
bool sorted= 1;
|
||||
uint first_sjm_table= MAX_TABLES;
|
||||
uint last_sjm_table= MAX_TABLES;
|
||||
DBUG_ENTER("make_join_readinfo");
|
||||
|
||||
|
||||
if (!join->select_lex->sj_nests.is_empty() &&
|
||||
@ -7947,6 +8187,9 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
|
||||
break;
|
||||
}
|
||||
|
||||
if (join->return_tab)
|
||||
goto restart;
|
||||
|
||||
switch (tab->type) {
|
||||
case JT_SYSTEM: // Only happens with left join
|
||||
case JT_CONST: // Only happens with left join
|
||||
@ -7959,7 +8202,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
|
||||
table->key_read=1;
|
||||
table->file->extra(HA_EXTRA_KEYREAD);
|
||||
}
|
||||
else if (!jcl || jcl > 4)
|
||||
else if ((!jcl || jcl > 4) && !tab->is_ref_for_hash_join())
|
||||
push_index_cond(tab, tab->ref.key,
|
||||
icp_other_tables_ok, idx_cond_fact_out);
|
||||
break;
|
||||
@ -7972,7 +8215,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
|
||||
table->key_read=1;
|
||||
table->file->extra(HA_EXTRA_KEYREAD);
|
||||
}
|
||||
else if (!jcl || jcl > 4)
|
||||
else if ((!jcl || jcl > 4) && !tab->is_ref_for_hash_join())
|
||||
push_index_cond(tab, tab->ref.key,
|
||||
icp_other_tables_ok, idx_cond_fact_out);
|
||||
break;
|
||||
@ -7988,7 +8231,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
|
||||
if (table->covering_keys.is_set(tab->ref.key) &&
|
||||
!table->no_keyread)
|
||||
table->enable_keyread();
|
||||
else if (!jcl || jcl > 4)
|
||||
else if ((!jcl || jcl > 4) &&!tab->is_ref_for_hash_join())
|
||||
push_index_cond(tab, tab->ref.key,
|
||||
icp_other_tables_ok, idx_cond_fact_out);
|
||||
break;
|
||||
@ -9894,7 +10137,7 @@ static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
|
||||
TABLE *tab= field->table;
|
||||
KEYUSE *use;
|
||||
for (use= stat->keyuse; use && use->table == tab; use++)
|
||||
if (possible_keys.is_set(use->key) &&
|
||||
if (!use->is_for_hash_join() && possible_keys.is_set(use->key) &&
|
||||
tab->key_info[use->key].key_part[use->keypart].field ==
|
||||
field)
|
||||
tab->const_key_parts[use->key]|= use->keypart_map;
|
||||
@ -11435,7 +11678,9 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
|
||||
bitmap_init(&table->tmp_set,
|
||||
(my_bitmap_map*) (bitmaps+ 2*bitmap_buffer_size(field_count)),
|
||||
field_count, FALSE);
|
||||
|
||||
bitmap_init(&table->eq_join_set,
|
||||
(my_bitmap_map*) (bitmaps+ 3*bitmap_buffer_size(field_count)),
|
||||
field_count, FALSE);
|
||||
/* write_set and all_set are copies of read_set */
|
||||
table->def_write_set= table->def_read_set;
|
||||
table->s->all_set= table->def_read_set;
|
||||
@ -11589,7 +11834,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
&tmpname, (uint) strlen(tmp_table_name)+1,
|
||||
&group_buff, (group && ! using_unique_constraint ?
|
||||
param->group_length : 0),
|
||||
&bitmaps, bitmap_buffer_size(field_count)*3,
|
||||
&bitmaps, bitmap_buffer_size(field_count)*4,
|
||||
NullS))
|
||||
{
|
||||
if (temp_pool_slot != MY_BIT_NONE)
|
||||
@ -12248,7 +12493,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
|
||||
&share, sizeof(*share),
|
||||
&field, (field_count + 1) * sizeof(Field*),
|
||||
&blob_field, (field_count+1) *sizeof(uint),
|
||||
&bitmaps, bitmap_buffer_size(field_count)*3,
|
||||
&bitmaps, bitmap_buffer_size(field_count)*4,
|
||||
NullS))
|
||||
return 0;
|
||||
|
||||
@ -14899,6 +15144,7 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
|
||||
JOIN_TAB *join_tab= field->table->reginfo.join_tab;
|
||||
// No need to change const test
|
||||
if (!field->table->const_table && join_tab &&
|
||||
!join_tab->is_ref_for_hash_join() &&
|
||||
(!join_tab->first_inner ||
|
||||
*join_tab->first_inner->on_expr_ref == root_cond))
|
||||
{
|
||||
@ -15215,19 +15461,22 @@ make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables,
|
||||
static Item *
|
||||
part_of_refkey(TABLE *table,Field *field)
|
||||
{
|
||||
if (!table->reginfo.join_tab)
|
||||
JOIN_TAB *join_tab= table->reginfo.join_tab;
|
||||
if (!join_tab)
|
||||
return (Item*) 0; // field from outer non-select (UPDATE,...)
|
||||
|
||||
uint ref_parts=table->reginfo.join_tab->ref.key_parts;
|
||||
uint ref_parts= join_tab->ref.key_parts;
|
||||
if (ref_parts)
|
||||
{
|
||||
KEY_PART_INFO *key_part=
|
||||
table->key_info[table->reginfo.join_tab->ref.key].key_part;
|
||||
|
||||
uint key= join_tab->ref.key;
|
||||
KEY *key_info= join_tab->get_keyinfo_by_key_no(key);
|
||||
KEY_PART_INFO *key_part= key_info->key_part;
|
||||
|
||||
for (uint part=0 ; part < ref_parts ; part++,key_part++)
|
||||
if (field->eq(key_part->field) &&
|
||||
!(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART)))
|
||||
return table->reginfo.join_tab->ref.items[part];
|
||||
return join_tab->ref.items[part];
|
||||
}
|
||||
return (Item*) 0;
|
||||
}
|
||||
@ -18795,6 +19044,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
tab->type = JT_RANGE;
|
||||
}
|
||||
|
||||
if (tab->cache && tab->cache->get_join_alg() == JOIN_CACHE::BNLH_JOIN_ALG)
|
||||
tab->type= JT_HASH;
|
||||
|
||||
/* table */
|
||||
if (table->derived_select_number)
|
||||
{
|
||||
@ -18858,7 +19110,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
/* Build "key", "key_len", and "ref" values and add them to item_list */
|
||||
if (tab->ref.key_parts)
|
||||
{
|
||||
KEY *key_info=table->key_info+ tab->ref.key;
|
||||
KEY *key_info= tab->get_keyinfo_by_key_no(tab->ref.key);
|
||||
register uint length;
|
||||
item_list.push_back(new Item_string(key_info->name,
|
||||
strlen(key_info->name),
|
||||
@ -18942,7 +19194,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
||||
ha_rows examined_rows;
|
||||
if (tab->select && tab->select->quick)
|
||||
examined_rows= tab->select->quick->records;
|
||||
else if (tab->type == JT_NEXT || tab->type == JT_ALL)
|
||||
else if (tab->type == JT_NEXT || tab->type == JT_ALL ||
|
||||
tab->type == JT_HASH)
|
||||
{
|
||||
if (tab->limit)
|
||||
examined_rows= tab->limit;
|
||||
@ -19683,6 +19936,40 @@ bool JOIN::change_result(select_result *res)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Set allowed types of join caches that can be used for join operations
|
||||
|
||||
@details
|
||||
The function sets a bitmap of allowed join buffers types in the field
|
||||
allowed_join_cache_types of this JOIN structure:
|
||||
bit 1 is set if tjoin buffers are allowed to be incremental
|
||||
bit 2 is set if the join buffers are allowed to be hashed
|
||||
but 3 is set if the join buffers are allowed to be used for BKA
|
||||
join algorithms.
|
||||
The allowed types are read from system variables.
|
||||
Besides the function sets maximum allowed join cache level that is
|
||||
also read from a system variable.
|
||||
*/
|
||||
|
||||
void JOIN::set_allowed_join_cache_types()
|
||||
{
|
||||
allowed_join_cache_types= 0;
|
||||
if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL))
|
||||
allowed_join_cache_types|= JOIN_CACHE_INCREMENTAL_BIT;
|
||||
if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_HASHED))
|
||||
allowed_join_cache_types|= JOIN_CACHE_HASHED_BIT;
|
||||
if (optimizer_flag(thd, OPTIMIZER_SWITCH_JOIN_CACHE_BKA))
|
||||
allowed_join_cache_types|= JOIN_CACHE_BKA_BIT;
|
||||
allowed_semijoin_with_cache=
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE);
|
||||
allowed_outer_join_with_cache=
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE);
|
||||
max_allowed_join_cache_level= thd->variables.join_cache_level;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@} (end of group Query_Optimizer)
|
||||
*/
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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:
|
||||
/**
|
||||
|
94
sql/table.cc
94
sql/table.cc
@ -2344,7 +2344,7 @@ partititon_err:
|
||||
/* 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 @@ partititon_err:
|
||||
(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()
|
||||
{
|
||||
|
Reference in New Issue
Block a user