diff options
author | Igor Babaev <igor@askmonty.org> | 2010-10-06 13:27:12 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2010-10-06 13:27:12 -0700 |
commit | d64ce287e344094fa4dec70d86b1392901a80b51 (patch) | |
tree | 5e25d464f11921aaf51073cdf80ed4fb8a174dfe /sql/sql_select.cc | |
parent | eecf033d81be2e5f059069dd7e68468ebb6f3ec4 (diff) | |
download | mariadb-git-d64ce287e344094fa4dec70d86b1392901a80b51.tar.gz |
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.
Diffstat (limited to 'sql/sql_select.cc')
-rwxr-xr-x | sql/sql_select.cc | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7aab9591960..c2381204a82 100755 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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); + } } /* |