mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
This first patch prepared for the task MDEV-13369:
"Optimization for equi-joins of derived tables with GROUP BY" should be considered rather as a 'proof of concept'. The task itself is targeted at an optimization that employs re-writing equi-joins with grouping derived tables / views into lateral derived tables. Here's an example of such transformation: select t1.a,t.max,t.min from t1 [left] join (select a, max(t2.b) max, min(t2.b) min from t2 group by t2.a) as t on t1.a=t.a; => select t1.a,tl.max,tl.min from t1 [left] join lateral (select a, max(t2.b) max, min(t2.b) min from t2 where t1.a=t2.a) as t on 1=1; The transformation pushes the equi-join condition t1.a=t.a into the derived table making it dependent on table t1. It means that for every row from t1 a new derived table must be filled out. However the size of any of these derived tables is just a fraction of the original derived table t. One could say that transformation 'splits' the rows used for the GROUP BY operation into separate groups performing aggregation for a group only in the case when there is a match for the current row of t1. Apparently the transformation may produce a query with a better performance only in the case when - the GROUP BY list refers only to fields returned by the derived table - there is an index I on one of the tables T used in FROM list of the specification of the derived table whose prefix covers the the fields from the proper beginning of the GROUP BY list or fields that are equal to those fields. Whether the result of the re-writing can be executed faster depends on many factors: - the size of the original derived table - the size of the table T - whether the index I is clustering for table T - whether the index I fully covers the GROUP BY list. This patch only tries to improve the chosen execution plan using this transformation. It tries to do it only when the chosen plan reaches the derived table by a key whose prefix covers all the fields of the derived table produced by the fields of the table T from the GROUP BY list. The code of the patch does not evaluates the cost of the improved plan. If certain conditions are met the transformation is applied.
This commit is contained in:
@ -614,6 +614,7 @@ typedef struct st_join_table {
|
||||
bool use_order() const; ///< Use ordering provided by chosen index?
|
||||
bool sort_table();
|
||||
bool remove_duplicates();
|
||||
Item *get_splitting_cond_for_grouping_derived(THD *thd);
|
||||
|
||||
} JOIN_TAB;
|
||||
|
||||
@ -1274,6 +1275,8 @@ public:
|
||||
and should be taken from the appropriate JOIN_TAB
|
||||
*/
|
||||
bool filesort_found_rows;
|
||||
|
||||
bool subq_exit_fl;
|
||||
|
||||
ROLLUP rollup; ///< Used with rollup
|
||||
|
||||
@ -1380,7 +1383,8 @@ public:
|
||||
|
||||
enum join_optimization_state { NOT_OPTIMIZED=0,
|
||||
OPTIMIZATION_IN_PROGRESS=1,
|
||||
OPTIMIZATION_DONE=2};
|
||||
OPTIMIZATION_IN_STAGE_2=2,
|
||||
OPTIMIZATION_DONE=3};
|
||||
// state of JOIN optimization
|
||||
enum join_optimization_state optimization_state;
|
||||
bool initialized; ///< flag to avoid double init_execution calls
|
||||
@ -1406,6 +1410,9 @@ public:
|
||||
/** Exec time only: TRUE <=> current group has been sent */
|
||||
bool group_sent;
|
||||
|
||||
bool is_for_splittable_grouping_derived;
|
||||
bool with_two_phase_optimization;
|
||||
|
||||
JOIN_TAB *sort_and_group_aggr_tab;
|
||||
|
||||
JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
|
||||
@ -1510,6 +1517,8 @@ public:
|
||||
bool prepare_stage2();
|
||||
int optimize();
|
||||
int optimize_inner();
|
||||
int optimize_stage2();
|
||||
void build_explain();
|
||||
int reinit();
|
||||
int init_execution();
|
||||
void exec();
|
||||
@ -1656,6 +1665,11 @@ public:
|
||||
bool need_order, bool distinct,
|
||||
const char *message);
|
||||
JOIN_TAB *first_breadth_first_tab() { return join_tab; }
|
||||
bool check_two_phase_optimization(THD *thd);
|
||||
bool check_for_splittable_grouping_derived(THD *thd);
|
||||
bool inject_cond_into_where(Item *injected_cond);
|
||||
bool push_splitting_cond_into_derived(THD *thd, Item *cond);
|
||||
bool improve_chosen_plan(THD *thd);
|
||||
private:
|
||||
/**
|
||||
Create a temporary table to be used for processing DISTINCT/ORDER
|
||||
@ -1693,6 +1707,7 @@ private:
|
||||
bool implicit_grouping;
|
||||
void cleanup_item_list(List<Item> &items) const;
|
||||
bool make_aggr_tables_info();
|
||||
|
||||
};
|
||||
|
||||
enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS};
|
||||
|
Reference in New Issue
Block a user