1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Merge branch '10.6' into 10.7

This commit is contained in:
Oleksandr Byelkin
2023-01-31 09:33:58 +01:00
140 changed files with 4096 additions and 705 deletions

View File

@ -3730,15 +3730,26 @@ bool JOIN::make_aggr_tables_info()
/*
If we have different sort & group then we must sort the data by group
and copy it to another tmp table
and copy it to another tmp table.
This code is also used if we are using distinct something
we haven't been able to store in the temporary table yet
like SEC_TO_TIME(SUM(...)).
3. Also, this is used when
- the query has Window functions,
- the GROUP BY operation is done with OrderedGroupBy algorithm.
In this case, the first temptable will contain pre-GROUP-BY data. Force
the creation of the second temporary table. Post-GROUP-BY dataset will be
written there, and then Window Function processing code will be able to
process it.
*/
if ((group_list &&
(!test_if_subpart(group_list, order) || select_distinct)) ||
(select_distinct && tmp_table_param.using_outer_summary_function))
{ /* Must copy to another table */
(select_distinct && tmp_table_param.using_outer_summary_function) ||
(group_list && !tmp_table_param.quick_group && // (3)
select_lex->have_window_funcs())) // (3)
{ /* Must copy to another table */
DBUG_PRINT("info",("Creating group table"));
calc_group_buffer(this, group_list);
@ -7891,6 +7902,7 @@ best_access_path(JOIN *join,
rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables
Json_writer_object trace_access_idx(thd);
double eq_ref_rows= 0.0, eq_ref_cost= 0.0;
/*
full text keys require special treatment
*/
@ -7935,7 +7947,10 @@ best_access_path(JOIN *join,
tmp= adjust_quick_cost(table->opt_range[key].cost, 1);
else
tmp= table->file->avg_io_cost();
tmp*= prev_record_reads(join_positions, idx, found_ref);
eq_ref_rows= prev_record_reads(join_positions, idx,
found_ref);
tmp*= eq_ref_rows;
eq_ref_cost= tmp;
records=1.0;
}
else
@ -8235,7 +8250,27 @@ best_access_path(JOIN *join,
(table->file->index_flags(start_key->key,0,1) &
HA_DO_RANGE_FILTER_PUSHDOWN))
{
double rows= record_count * records;
double rows;
if (type == JT_EQ_REF)
{
/*
Treat EQ_REF access in a special way:
1. We have no cost for index-only read. Assume its cost is 50% of
the cost of the full read.
2. A regular ref access will do #record_count lookups, but eq_ref
has "lookup cache" which reduces the number of lookups made.
The estimation code uses prev_record_reads() call to estimate:
tmp = prev_record_reads(join_positions, idx, found_ref);
Set the effective number of rows from "tmp" here.
*/
keyread_tmp= COST_ADD(eq_ref_cost / 2, s->startup_cost);
rows= eq_ref_rows;
}
else
rows= record_count * records;
/*
If we use filter F with selectivity s the the cost of fetching data
@ -8278,10 +8313,6 @@ best_access_path(JOIN *join,
we cannot use filters as the cost calculation below would cause
tmp to become negative. The future resultion is to not limit
cost with worst_seek.
We cannot use filter with JT_EQ_REF as in this case 'tmp' is
number of rows from prev_record_read() and keyread_tmp is 0. These
numbers are not usable with rowid filter code.
*/
double access_cost_factor= MY_MIN((rows - keyread_tmp) / rows, 1.0);
if (!(records < s->worst_seeks &&
@ -8289,7 +8320,7 @@ best_access_path(JOIN *join,
trace_access_idx.add("rowid_filter_skipped", "worst/max seeks clipping");
else if (access_cost_factor <= 0.0)
trace_access_idx.add("rowid_filter_skipped", "cost_factor <= 0");
else if (type != JT_EQ_REF)
else
{
filter=
table->best_range_rowid_filter_for_partial_join(start_key->key,
@ -22733,11 +22764,17 @@ end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
/*
@brief
Perform a GROUP BY operation over a stream of rows ordered by their group.
The result is sent into join->result.
Perform OrderedGroupBy operation and write the output into join->result.
@detail
Also applies HAVING, etc.
The input stream is ordered by the GROUP BY expression, so groups come
one after another. We only need to accumulate the aggregate value, when
a GROUP BY group ends, check the HAVING and send the group.
Note that the output comes in the GROUP BY order, which is required by
the MySQL's GROUP BY semantics. No further sorting is needed.
@seealso end_write_group() also implements SortAndGroup
*/
enum_nested_loop_state
@ -22937,13 +22974,26 @@ end:
/*
@brief
Perform a GROUP BY operation over rows coming in arbitrary order.
This is done by looking up the group in a temp.table and updating group
values.
Perform GROUP BY operation over rows coming in arbitrary order: use
TemporaryTableWithPartialSums algorithm.
@detail
The TemporaryTableWithPartialSums algorithm is:
CREATE TEMPORARY TABLE tmp (
group_by_columns PRIMARY KEY,
partial_sum
);
for each row R in join output {
INSERT INTO tmp (R.group_by_columns, R.sum_value)
ON DUPLICATE KEY UPDATE partial_sum=partial_sum + R.sum_value;
}
@detail
Also applies HAVING, etc.
@seealso end_unique_update()
*/
static enum_nested_loop_state
@ -23096,13 +23146,15 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/*
@brief
Perform a GROUP BY operation over a stream of rows ordered by their group.
Write the result into a temporary table.
Perform OrderedGroupBy operation and write the output into the temporary
table (join_tab->table).
@detail
Also applies HAVING, etc.
The input stream is ordered by the GROUP BY expression, so groups come
one after another. We only need to accumulate the aggregate value, when
a GROUP BY group ends, check the HAVING and write the group.
The rows are written into temptable so e.g. filesort can read them.
@seealso end_send_group() also implements OrderedGroupBy
*/
enum_nested_loop_state