Commit 6b1c78e7 authored by Igor Babaev's avatar Igor Babaev

Merge

parents d91422f0 716e8416
...@@ -1449,4 +1449,63 @@ group by t2.pk; ...@@ -1449,4 +1449,63 @@ group by t2.pk;
pk t pk t
2001 3001 2001 3001
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
#
# Bug#57024: Poor performance when conjunctive condition over the outer
# table is used in the on condition of an outer join
#
create table t1 (a int);
insert into t1 values (NULL), (NULL), (NULL), (NULL);
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 values (4), (2), (1), (3);
create table t2 like t1;
insert into t2 select if(t1.a is null, 10, t1.a) from t1;
create table t3 (a int, b int, index idx(a));
insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101);
analyze table t1,t2,t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t2 analyze status OK
test.t3 analyze status OK
flush status;
select sum(t3.b) from t1 left join t3 on t3.a=t1.a and t1.a is not null;
sum(t3.b)
1006
show status like "handler_read%";
Variable_name Value
Handler_read_first 0
Handler_read_key 4
Handler_read_next 5
Handler_read_prev 0
Handler_read_rnd 0
Handler_read_rnd_next 1048581
flush status;
select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10;
sum(t3.b)
1006
show status like "handler_read%";
Variable_name Value
Handler_read_first 0
Handler_read_key 4
Handler_read_next 5
Handler_read_prev 0
Handler_read_rnd 0
Handler_read_rnd_next 1048581
drop table t1,t2,t3;
End of 5.1 tests End of 5.1 tests
...@@ -1029,4 +1029,48 @@ select t2.pk, ...@@ -1029,4 +1029,48 @@ select t2.pk,
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
--echo #
--echo # Bug#57024: Poor performance when conjunctive condition over the outer
--echo # table is used in the on condition of an outer join
--echo #
create table t1 (a int);
insert into t1 values (NULL), (NULL), (NULL), (NULL);
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 values (4), (2), (1), (3);
create table t2 like t1;
insert into t2 select if(t1.a is null, 10, t1.a) from t1;
create table t3 (a int, b int, index idx(a));
insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101);
analyze table t1,t2,t3;
flush status;
select sum(t3.b) from t1 left join t3 on t3.a=t1.a and t1.a is not null;
show status like "handler_read%";
flush status;
select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10;
show status like "handler_read%";
drop table t1,t2,t3;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -6632,6 +6632,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ...@@ -6632,6 +6632,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (tmp_cond) if (tmp_cond)
{ {
JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab; JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
Item **sel_cond_ref= tab < first_inner_tab ?
&first_inner_tab->on_precond :
&tab->select_cond;
/* /*
First add the guards for match variables of First add the guards for match variables of
all embedding outer join operations. all embedding outer join operations.
...@@ -6654,14 +6657,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ...@@ -6654,14 +6657,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
tmp_cond->quick_fix_field(); tmp_cond->quick_fix_field();
/* Add the predicate to other pushed down predicates */ /* Add the predicate to other pushed down predicates */
DBUG_PRINT("info", ("Item_cond_and")); DBUG_PRINT("info", ("Item_cond_and"));
cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond : *sel_cond_ref= !(*sel_cond_ref) ?
new Item_cond_and(cond_tab->select_cond, tmp_cond :
tmp_cond); new Item_cond_and(*sel_cond_ref, tmp_cond);
DBUG_PRINT("info", ("Item_cond_and 0x%lx", DBUG_PRINT("info", ("Item_cond_and 0x%lx",
(ulong)cond_tab->select_cond)); (ulong)(*sel_cond_ref)));
if (!cond_tab->select_cond) if (!(*sel_cond_ref))
DBUG_RETURN(1); DBUG_RETURN(1);
cond_tab->select_cond->quick_fix_field(); (*sel_cond_ref)->quick_fix_field();
} }
} }
first_inner_tab= first_inner_tab->first_upper; first_inner_tab= first_inner_tab->first_upper;
...@@ -11646,7 +11649,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) ...@@ -11646,7 +11649,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
return (*join_tab->next_select)(join,join_tab+1,end_of_records); return (*join_tab->next_select)(join,join_tab+1,end_of_records);
int error; int error;
enum_nested_loop_state rc; enum_nested_loop_state rc= NESTED_LOOP_OK;
READ_RECORD *info= &join_tab->read_record; READ_RECORD *info= &join_tab->read_record;
if (join->resume_nested_loop) if (join->resume_nested_loop)
...@@ -11674,11 +11677,16 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) ...@@ -11674,11 +11677,16 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
/* Set first_unmatched for the last inner table of this group */ /* Set first_unmatched for the last inner table of this group */
join_tab->last_inner->first_unmatched= join_tab; join_tab->last_inner->first_unmatched= join_tab;
if (join_tab->on_precond && !join_tab->on_precond->val_int())
rc= NESTED_LOOP_NO_MORE_ROWS;
} }
join->thd->row_count= 0; join->thd->row_count= 0;
error= (*join_tab->read_first_record)(join_tab); if (rc != NESTED_LOOP_NO_MORE_ROWS)
rc= evaluate_join_record(join, join_tab, error); {
error= (*join_tab->read_first_record)(join_tab);
rc= evaluate_join_record(join, join_tab, error);
}
} }
while (rc == NESTED_LOOP_OK) while (rc == NESTED_LOOP_OK)
......
...@@ -154,7 +154,9 @@ typedef struct st_join_table { ...@@ -154,7 +154,9 @@ typedef struct st_join_table {
TABLE *table; TABLE *table;
KEYUSE *keyuse; /**< pointer to first used key */ KEYUSE *keyuse; /**< pointer to first used key */
SQL_SELECT *select; SQL_SELECT *select;
COND *select_cond; COND *select_cond;
COND *on_precond; /**< part of on condition to check before
accessing the first inner table */
QUICK_SELECT_I *quick; QUICK_SELECT_I *quick;
Item **on_expr_ref; /**< pointer to the associated on expression */ Item **on_expr_ref; /**< pointer to the associated on expression */
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */ COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment