mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Ported the fix for bug #57024 (a performance issue for outer joins).
Employed the same kind of optimization as in the fix for the cases when join buffer is used. The optimization performs early evaluation of the conditions from on expression with table references to only outer tables of an outer join.
This commit is contained in:
@ -7090,9 +7090,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
used_tables2|= current_map;
|
||||
COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
|
||||
current_map, FALSE);
|
||||
add_cond_and_fix(&tmp_cond, tab->on_precond);
|
||||
if (tmp_cond)
|
||||
{
|
||||
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
|
||||
all embedding outer join operations.
|
||||
@ -7115,15 +7119,15 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
tmp_cond->quick_fix_field();
|
||||
/* Add the predicate to other pushed down predicates */
|
||||
DBUG_PRINT("info", ("Item_cond_and"));
|
||||
cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
|
||||
new Item_cond_and(cond_tab->select_cond,
|
||||
tmp_cond);
|
||||
*sel_cond_ref= !(*sel_cond_ref) ?
|
||||
tmp_cond :
|
||||
new Item_cond_and(*sel_cond_ref, tmp_cond);
|
||||
DBUG_PRINT("info", ("Item_cond_and 0x%lx",
|
||||
(ulong)cond_tab->select_cond));
|
||||
if (!cond_tab->select_cond)
|
||||
DBUG_RETURN(1);
|
||||
cond_tab->select_cond->update_used_tables();
|
||||
cond_tab->select_cond->quick_fix_field();
|
||||
(ulong)(*sel_cond_ref)));
|
||||
if (!(*sel_cond_ref))
|
||||
DBUG_RETURN(1);
|
||||
(*sel_cond_ref)->quick_fix_field();
|
||||
(*sel_cond_ref)->update_used_tables();
|
||||
if (cond_tab->select)
|
||||
cond_tab->select->cond= cond_tab->select_cond;
|
||||
}
|
||||
@ -13246,7 +13250,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
|
||||
DBUG_RETURN(nls);
|
||||
}
|
||||
int error;
|
||||
enum_nested_loop_state rc;
|
||||
enum_nested_loop_state rc= NESTED_LOOP_OK;
|
||||
READ_RECORD *info= &join_tab->read_record;
|
||||
|
||||
if (join_tab->flush_weedout_table)
|
||||
@ -13279,18 +13283,21 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
|
||||
|
||||
/* Set first_unmatched for the last inner table of this group */
|
||||
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;
|
||||
|
||||
if (join_tab->loosescan_match_tab)
|
||||
join_tab->loosescan_match_tab->found_match= FALSE;
|
||||
|
||||
error= (*join_tab->read_first_record)(join_tab);
|
||||
|
||||
if (join_tab->keep_current_rowid)
|
||||
join_tab->table->file->position(join_tab->table->record[0]);
|
||||
|
||||
rc= evaluate_join_record(join, join_tab, error);
|
||||
if (rc != NESTED_LOOP_NO_MORE_ROWS)
|
||||
{
|
||||
error= (*join_tab->read_first_record)(join_tab);
|
||||
if (join_tab->keep_current_rowid)
|
||||
join_tab->table->file->position(join_tab->table->record[0]);
|
||||
rc= evaluate_join_record(join, join_tab, error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user