1
0
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:
Igor Babaev
2010-10-06 13:27:12 -07:00
parent f1d42ec940
commit 79087c9e07
8 changed files with 420 additions and 88 deletions

View File

@ -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);
}
}
/*