mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Fixed limit optimization in range optimizer
The issue was that when limit is used, SQL_SELECT::test_quick_select would set the cost of table scan to be unreasonable high to force a range to be used. The problem with this approach was that range was used even when the cost of range, when it would only read 'limit rows' would be higher than the cost of a table scan. This patch fixes it by not accepting ranges when the range can never have a lower cost than a table scan, even if every row would match the WHERE clause.
This commit is contained in:
parent
b66cdbd1ea
commit
009db2288b
19 changed files with 154 additions and 85 deletions
|
@ -799,6 +799,7 @@ INSERT INTO t2 SELECT * FROM t1 ORDER BY id;
|
|||
|
||||
EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20;
|
||||
EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 4000;
|
||||
EXPLAIN SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 6000;
|
||||
EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 10 AND 12 ORDER BY c3 LIMIT 20;
|
||||
EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000;
|
||||
|
||||
|
|
|
@ -6575,7 +6575,7 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno,
|
|||
RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *mrr_mode,
|
||||
uint *mrr_mode, ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
int error;
|
||||
|
@ -6636,7 +6636,7 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno,
|
|||
&m_partition_part_key_multi_range_hld[i],
|
||||
m_part_mrr_range_length[i],
|
||||
&m_mrr_buffer_size[i],
|
||||
&tmp_mrr_mode, &part_cost);
|
||||
&tmp_mrr_mode, limit, &part_cost);
|
||||
if (tmp_rows == HA_POS_ERROR)
|
||||
{
|
||||
m_part_spec= save_part_spec;
|
||||
|
|
|
@ -919,7 +919,7 @@ public:
|
|||
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *mrr_mode,
|
||||
uint *mrr_mode, ha_rows limit,
|
||||
Cost_estimate *cost) override;
|
||||
ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
uint key_parts, uint *bufsz,
|
||||
|
|
|
@ -2790,6 +2790,7 @@ public:
|
|||
double comp_cost; /* Cost of comparing found rows with WHERE clause */
|
||||
double copy_cost; /* Copying the data to 'record' */
|
||||
double mem_cost; /* cost of used memory */
|
||||
double limit_cost; /* Total cost when restricting rows with limit */
|
||||
|
||||
static constexpr double IO_COEFF= 1;
|
||||
static constexpr double CPU_COEFF= 1;
|
||||
|
@ -2853,8 +2854,8 @@ public:
|
|||
{
|
||||
avg_io_cost= 1.0;
|
||||
idx_avg_io_cost= 1.0;
|
||||
io_count= idx_io_count= cpu_cost= idx_cpu_cost= mem_cost= import_cost=
|
||||
comp_cost= copy_cost= 0.0;
|
||||
io_count= idx_io_count= cpu_cost= idx_cpu_cost= mem_cost= import_cost= 0.0;
|
||||
comp_cost= copy_cost= limit_cost= 0.0;
|
||||
}
|
||||
|
||||
void multiply(double m)
|
||||
|
@ -2865,6 +2866,7 @@ public:
|
|||
idx_cpu_cost *= m;
|
||||
import_cost *= m;
|
||||
comp_cost *= m;
|
||||
limit_cost*= m;
|
||||
/* Don't multiply mem_cost */
|
||||
}
|
||||
|
||||
|
@ -2890,6 +2892,7 @@ public:
|
|||
idx_cpu_cost += cost->idx_cpu_cost;
|
||||
import_cost += cost->import_cost;
|
||||
comp_cost+= cost->comp_cost;
|
||||
limit_cost+= cost->limit_cost;
|
||||
}
|
||||
|
||||
void add_io(double add_io_cnt, double add_avg_cost)
|
||||
|
@ -4093,7 +4096,7 @@ public:
|
|||
virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *mrr_mode,
|
||||
uint *mrr_mode, ha_rows limit,
|
||||
Cost_estimate *cost);
|
||||
virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
uint key_parts, uint *bufsz,
|
||||
|
@ -4102,6 +4105,13 @@ public:
|
|||
uint n_ranges, uint mrr_mode,
|
||||
HANDLER_BUFFER *buf);
|
||||
virtual int multi_range_read_next(range_id_t *range_info);
|
||||
private:
|
||||
inline void calculate_costs(Cost_estimate *cost, uint keyno,
|
||||
uint ranges, uint flags,
|
||||
ha_rows total_rows,
|
||||
ulonglong io_blocks,
|
||||
ulonglong unassigned_single_point_ranges);
|
||||
public:
|
||||
/*
|
||||
Return string representation of the MRR plan.
|
||||
|
||||
|
|
|
@ -22,6 +22,50 @@
|
|||
#include "rowid_filter.h"
|
||||
#include "optimizer_defaults.h"
|
||||
|
||||
|
||||
|
||||
/* The following calculation is the same as in multi_range_read_info() */
|
||||
|
||||
void handler::calculate_costs(Cost_estimate *cost, uint keyno,
|
||||
uint n_ranges, uint flags,
|
||||
ha_rows total_rows,
|
||||
ulonglong io_blocks,
|
||||
ulonglong unassigned_single_point_ranges)
|
||||
{
|
||||
double key_cost;
|
||||
cost->reset();
|
||||
cost->avg_io_cost= cost->idx_avg_io_cost= 0; // Not used!
|
||||
|
||||
if (!is_clustering_key(keyno))
|
||||
{
|
||||
key_cost= ha_keyread_time(keyno, n_ranges, total_rows, io_blocks);
|
||||
cost->idx_cpu_cost= key_cost;
|
||||
|
||||
if (!(flags & HA_MRR_INDEX_ONLY))
|
||||
{
|
||||
/* ha_rnd_pos_time includes ROW_COPY_COST */
|
||||
cost->cpu_cost= ha_rnd_pos_time(total_rows);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Index only read */
|
||||
cost->copy_cost= rows2double(total_rows) * KEY_COPY_COST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clustered index */
|
||||
io_blocks+= unassigned_single_point_ranges;
|
||||
key_cost= ha_keyread_time(keyno, n_ranges, total_rows, io_blocks);
|
||||
cost->idx_cpu_cost= key_cost;
|
||||
cost->copy_cost= rows2double(total_rows) * ROW_COPY_COST;
|
||||
}
|
||||
cost->comp_cost= (rows2double(total_rows) * WHERE_COST +
|
||||
MULTI_RANGE_READ_SETUP_COST);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Default MRR implementation (MRR to non-MRR converter)
|
||||
***************************************************************************/
|
||||
|
@ -57,10 +101,12 @@
|
|||
contain scan parameters.
|
||||
*/
|
||||
|
||||
|
||||
ha_rows
|
||||
handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param, uint n_ranges_arg,
|
||||
uint *bufsz, uint *flags,
|
||||
ha_rows top_limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
KEY_MULTI_RANGE range;
|
||||
|
@ -303,40 +349,22 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
|||
|
||||
if (total_rows != HA_POS_ERROR)
|
||||
{
|
||||
double key_cost;
|
||||
set_if_smaller(total_rows, max_rows);
|
||||
|
||||
/* The following calculation is the same as in multi_range_read_info(): */
|
||||
*flags |= HA_MRR_USE_DEFAULT_IMPL;
|
||||
cost->reset();
|
||||
cost->avg_io_cost= cost->idx_avg_io_cost= 0; // Not used!
|
||||
|
||||
if (!is_clustering_key(keyno))
|
||||
calculate_costs(cost, keyno, n_ranges, *flags, total_rows,
|
||||
io_blocks, unassigned_single_point_ranges);
|
||||
if (top_limit < total_rows)
|
||||
{
|
||||
key_cost= ha_keyread_time(keyno, n_ranges, total_rows, io_blocks);
|
||||
cost->idx_cpu_cost= key_cost;
|
||||
|
||||
if (!(*flags & HA_MRR_INDEX_ONLY))
|
||||
{
|
||||
/* ha_rnd_pos_time includes ROW_COPY_COST */
|
||||
cost->cpu_cost= ha_rnd_pos_time(total_rows);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Index only read */
|
||||
cost->copy_cost= rows2double(total_rows) * KEY_COPY_COST;
|
||||
}
|
||||
/*
|
||||
Calculate what the cost would be if we only have to read 'top_limit'
|
||||
rows. This is the lowest possible cost fwhen using the range
|
||||
when we find the 'accepted rows' at once.
|
||||
*/
|
||||
Cost_estimate limit_cost;
|
||||
calculate_costs(&limit_cost, keyno, n_ranges, *flags, top_limit,
|
||||
io_blocks, unassigned_single_point_ranges);
|
||||
cost->limit_cost= limit_cost.total_cost();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clustered index */
|
||||
io_blocks+= unassigned_single_point_ranges;
|
||||
key_cost= ha_keyread_time(keyno, n_ranges, total_rows, io_blocks);
|
||||
cost->idx_cpu_cost= key_cost;
|
||||
cost->copy_cost= rows2double(total_rows) * ROW_COPY_COST;
|
||||
}
|
||||
cost->comp_cost= (rows2double(total_rows) * WHERE_COST +
|
||||
MULTI_RANGE_READ_SETUP_COST);
|
||||
}
|
||||
DBUG_PRINT("statistics",
|
||||
("key: %s rows: %llu total_cost: %.3f io_blocks: %llu "
|
||||
|
@ -1717,8 +1745,9 @@ ha_rows DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows,
|
|||
*/
|
||||
|
||||
ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param, uint n_ranges,
|
||||
uint *bufsz, uint *flags, Cost_estimate *cost)
|
||||
void *seq_init_param, uint n_ranges,
|
||||
uint *bufsz, uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
ha_rows rows;
|
||||
uint def_flags= *flags;
|
||||
|
@ -1728,7 +1757,9 @@ ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
|||
seq_init_param,
|
||||
n_ranges,
|
||||
&def_bufsz,
|
||||
&def_flags, cost);
|
||||
&def_flags,
|
||||
limit,
|
||||
cost);
|
||||
if (rows == HA_POS_ERROR)
|
||||
{
|
||||
/* Default implementation can't perform MRR scan => we can't either */
|
||||
|
|
|
@ -576,7 +576,7 @@ public:
|
|||
|
||||
ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param, uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost);
|
||||
uint *flags, ha_rows limit, Cost_estimate *cost);
|
||||
|
||||
int dsmrr_explain_info(uint mrr_mode, char *str, size_t size);
|
||||
private:
|
||||
|
|
|
@ -345,7 +345,8 @@ struct st_index_scan_info;
|
|||
struct st_ror_scan_info;
|
||||
|
||||
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts);
|
||||
static ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
|
||||
static ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit,
|
||||
bool index_only,
|
||||
SEL_ARG *tree, bool update_tbl_stats,
|
||||
uint *mrr_flags, uint *bufsize,
|
||||
Cost_estimate *cost, bool *is_ror_scan);
|
||||
|
@ -356,7 +357,8 @@ QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
|
|||
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
|
||||
bool index_read_must_be_used,
|
||||
bool for_range_access,
|
||||
double read_time);
|
||||
double read_time, ha_rows limit,
|
||||
bool using_table_scan);
|
||||
static
|
||||
TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
|
||||
double read_time);
|
||||
|
@ -370,7 +372,9 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
|
|||
double read_time);
|
||||
static
|
||||
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
|
||||
double read_time, bool named_trace= false);
|
||||
double read_time, ha_rows limit,
|
||||
bool named_trace,
|
||||
bool using_table_scan);
|
||||
static
|
||||
TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
|
||||
TRP_INDEX_MERGE *imerge_trp,
|
||||
|
@ -2715,21 +2719,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||
else
|
||||
{
|
||||
read_time= head->file->ha_scan_and_compare_time(records);
|
||||
|
||||
/*
|
||||
Force the detection of range access if LIMIT is used.
|
||||
The idea is that we want to store all possible range
|
||||
accesses to see if we can use them to resolve an ORDER BY.
|
||||
Ranges with too high costs will be pruned in best_access_path().
|
||||
|
||||
The test for read_time is there only to not modify read_time if
|
||||
ha_scan_and_compare_time() returned a really big value
|
||||
*/
|
||||
if (limit < records && read_time < (double) records * 2)
|
||||
{
|
||||
read_time= (double) records * 2; // Force to use index
|
||||
if (limit < records)
|
||||
notnull_cond= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
possible_keys.clear_all();
|
||||
|
@ -2959,7 +2950,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||
/* Get best 'range' plan and prepare data for making other plans */
|
||||
if ((range_trp= get_key_scans_params(¶m, tree,
|
||||
only_single_index_range_scan,
|
||||
true, best_read_time)))
|
||||
true, best_read_time, limit,
|
||||
1)))
|
||||
{
|
||||
best_trp= range_trp;
|
||||
best_read_time= best_trp->read_cost;
|
||||
|
@ -3025,7 +3017,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||
Json_writer_array trace_idx_merge(thd, "analyzing_index_merge_union");
|
||||
while ((imerge= it++))
|
||||
{
|
||||
new_conj_trp= get_best_disjunct_quick(¶m, imerge, best_read_time);
|
||||
new_conj_trp= get_best_disjunct_quick(¶m, imerge, best_read_time,
|
||||
limit, 0, 1);
|
||||
if (new_conj_trp)
|
||||
param.table->set_opt_range_condition_rows(new_conj_trp->records);
|
||||
if (new_conj_trp &&
|
||||
|
@ -5210,7 +5203,9 @@ static double get_sweep_read_cost(const PARAM *param, ha_rows records,
|
|||
|
||||
static
|
||||
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
|
||||
double read_time, bool named_trace)
|
||||
double read_time, ha_rows limit,
|
||||
bool named_trace,
|
||||
bool using_table_scan)
|
||||
{
|
||||
SEL_TREE **ptree;
|
||||
TRP_INDEX_MERGE *imerge_trp= NULL;
|
||||
|
@ -5274,7 +5269,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
|
|||
"tree in SEL_IMERGE"););
|
||||
Json_writer_object trace_idx(thd);
|
||||
if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE,
|
||||
read_time)))
|
||||
read_time, limit, using_table_scan)))
|
||||
{
|
||||
/*
|
||||
One of index scans in this index_merge is more expensive than entire
|
||||
|
@ -5624,7 +5619,8 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
|
|||
DBUG_ASSERT(imerge->trees_next>imerge->trees);
|
||||
|
||||
if (imerge->trees_next-imerge->trees > 1)
|
||||
trp= get_best_disjunct_quick(param, imerge, read_time, true);
|
||||
trp= get_best_disjunct_quick(param, imerge, read_time, HA_POS_ERROR, true,
|
||||
0);
|
||||
else
|
||||
{
|
||||
/*
|
||||
|
@ -7594,7 +7590,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
|
|||
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
|
||||
bool index_read_must_be_used,
|
||||
bool for_range_access,
|
||||
double read_time)
|
||||
double read_time, ha_rows limit,
|
||||
bool using_table_scan)
|
||||
{
|
||||
uint idx, UNINIT_VAR(best_idx);
|
||||
SEL_ARG *key_to_read= NULL;
|
||||
|
@ -7646,7 +7643,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
|
|||
Json_writer_object trace_idx(thd);
|
||||
trace_idx.add("index", param->table->key_info[keynr].name);
|
||||
|
||||
found_records= check_quick_select(param, idx, read_index_only, key,
|
||||
found_records= check_quick_select(param, idx, limit, read_index_only, key,
|
||||
for_range_access, &mrr_flags,
|
||||
&buf_size, &cost, &is_ror_scan);
|
||||
|
||||
|
@ -7680,19 +7677,29 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
|
|||
trace_range.end();
|
||||
|
||||
if (unlikely(trace_idx.trace_started()))
|
||||
{
|
||||
trace_idx.
|
||||
add("rowid_ordered", is_ror_scan).
|
||||
add("using_mrr", !(mrr_flags & HA_MRR_USE_DEFAULT_IMPL)).
|
||||
add("index_only", read_index_only).
|
||||
add("rows", found_records).
|
||||
add("cost", found_read_time);
|
||||
if (using_table_scan && cost.limit_cost != 0.0)
|
||||
trace_idx.add("cost_with_limit", cost.limit_cost);
|
||||
}
|
||||
}
|
||||
if (is_ror_scan)
|
||||
{
|
||||
tree->n_ror_scans++;
|
||||
tree->ror_scans_map.set_bit(idx);
|
||||
}
|
||||
if (read_time > found_read_time)
|
||||
/*
|
||||
Use range if best range so far or if we are comparing to a table scan
|
||||
and the cost with limit approximation is better than the table scan
|
||||
*/
|
||||
if (read_time > found_read_time ||
|
||||
(using_table_scan && cost.limit_cost != 0.0 &&
|
||||
read_time > cost.limit_cost))
|
||||
{
|
||||
read_time= found_read_time;
|
||||
best_records= found_records;
|
||||
|
@ -7700,6 +7707,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
|
|||
best_idx= idx;
|
||||
best_mrr_flags= mrr_flags;
|
||||
best_buf_size= buf_size;
|
||||
using_table_scan= 0;
|
||||
trace_idx.add("chosen", true);
|
||||
}
|
||||
else if (unlikely(trace_idx.trace_started()))
|
||||
|
@ -11703,7 +11711,8 @@ static bool check_if_first_key_part_has_only_one_value(SEL_ARG *arg)
|
|||
*/
|
||||
|
||||
static
|
||||
ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
|
||||
ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit,
|
||||
bool index_only,
|
||||
SEL_ARG *tree, bool update_tbl_stats,
|
||||
uint *mrr_flags, uint *bufsize, Cost_estimate *cost,
|
||||
bool *is_ror_scan)
|
||||
|
@ -11765,7 +11774,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
|
|||
*/
|
||||
if (param->table->pos_in_table_list->is_non_derived())
|
||||
rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
|
||||
bufsize, mrr_flags, cost);
|
||||
bufsize, mrr_flags, limit, cost);
|
||||
param->quick_rows[keynr]= rows;
|
||||
if (rows != HA_POS_ERROR)
|
||||
{
|
||||
|
|
|
@ -7400,7 +7400,8 @@ int ha_connect::multi_range_read_next(range_id_t *range_info)
|
|||
ha_rows ha_connect::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost)
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
/*
|
||||
This call is here because there is no location where this->table would
|
||||
|
@ -7414,7 +7415,7 @@ ha_rows ha_connect::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
|||
*flags|= HA_MRR_USE_DEFAULT_IMPL;
|
||||
|
||||
ha_rows rows= ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges,
|
||||
bufsz, flags, cost);
|
||||
bufsz, flags, limit, cost);
|
||||
xp->g->Mrr= !(*flags & HA_MRR_USE_DEFAULT_IMPL);
|
||||
return rows;
|
||||
} // end of multi_range_read_info_const
|
||||
|
|
|
@ -502,7 +502,8 @@ int index_prev(uchar *buf);
|
|||
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost);
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost);
|
||||
ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
uint key_parts, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost);
|
||||
|
|
|
@ -19972,6 +19972,7 @@ ha_innobase::multi_range_read_info_const(
|
|||
uint n_ranges,
|
||||
uint* bufsz,
|
||||
uint* flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate* cost)
|
||||
{
|
||||
/* See comments in ha_myisam::multi_range_read_info_const */
|
||||
|
@ -19981,8 +19982,9 @@ ha_innobase::multi_range_read_info_const(
|
|||
*flags |= HA_MRR_USE_DEFAULT_IMPL;
|
||||
}
|
||||
|
||||
ha_rows res= m_ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges,
|
||||
bufsz, flags, cost);
|
||||
ha_rows res= m_ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param,
|
||||
n_ranges,
|
||||
bufsz, flags, limit, cost);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -383,6 +383,7 @@ public:
|
|||
uint n_ranges,
|
||||
uint* bufsz,
|
||||
uint* flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate* cost) override;
|
||||
|
||||
/** Initialize multi range read and get information.
|
||||
|
|
|
@ -4208,7 +4208,8 @@ int ha_maria::multi_range_read_next(range_id_t *range_info)
|
|||
ha_rows ha_maria::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost)
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
/*
|
||||
This call is here because there is no location where this->table would
|
||||
|
@ -4217,7 +4218,7 @@ ha_rows ha_maria::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
|||
*/
|
||||
ds_mrr.init(this, table);
|
||||
return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
|
||||
flags, cost);
|
||||
flags, limit, cost);
|
||||
}
|
||||
|
||||
ha_rows ha_maria::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
|
|
|
@ -175,7 +175,8 @@ public:
|
|||
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost) override final;
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost) override final;
|
||||
ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
uint key_parts, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost) override final;
|
||||
|
|
|
@ -12314,6 +12314,7 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno,
|
|||
uint n_ranges,
|
||||
uint *bufsz,
|
||||
uint *flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
@ -12321,7 +12322,8 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno,
|
|||
KEY *key_info = &(table->key_info[keyno]);
|
||||
if (mrn_is_geo_key(key_info)) {
|
||||
rows = handler::multi_range_read_info_const(keyno, seq, seq_init_param,
|
||||
n_ranges, bufsz, flags, cost);
|
||||
n_ranges, bufsz, flags, limit,
|
||||
cost);
|
||||
DBUG_RETURN(rows);
|
||||
}
|
||||
MRN_SET_WRAP_SHARE_KEY(share, table->s);
|
||||
|
@ -12330,7 +12332,7 @@ ha_rows ha_mroonga::wrapper_multi_range_read_info_const(uint keyno,
|
|||
set_pk_bitmap();
|
||||
rows = wrap_handler->multi_range_read_info_const(keyno, seq, seq_init_param,
|
||||
n_ranges, bufsz, flags,
|
||||
cost);
|
||||
limit, cost);
|
||||
MRN_SET_BASE_SHARE_KEY(share, table->s);
|
||||
MRN_SET_BASE_TABLE_KEY(this, table);
|
||||
DBUG_RETURN(rows);
|
||||
|
@ -12342,20 +12344,21 @@ ha_rows ha_mroonga::storage_multi_range_read_info_const(uint keyno,
|
|||
uint n_ranges,
|
||||
uint *bufsz,
|
||||
uint *flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
ha_rows rows = handler::multi_range_read_info_const(keyno, seq,
|
||||
seq_init_param,
|
||||
n_ranges, bufsz, flags,
|
||||
cost);
|
||||
limit, cost);
|
||||
DBUG_RETURN(rows);
|
||||
}
|
||||
|
||||
ha_rows ha_mroonga::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags,
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
MRN_DBUG_ENTER_METHOD();
|
||||
|
@ -12364,11 +12367,11 @@ ha_rows ha_mroonga::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
|||
{
|
||||
rows = wrapper_multi_range_read_info_const(keyno, seq, seq_init_param,
|
||||
n_ranges, bufsz,
|
||||
flags, cost);
|
||||
flags, limit, cost);
|
||||
} else {
|
||||
rows = storage_multi_range_read_info_const(keyno, seq, seq_init_param,
|
||||
n_ranges, bufsz,
|
||||
flags, cost);
|
||||
flags, limit, cost);
|
||||
}
|
||||
DBUG_RETURN(rows);
|
||||
}
|
||||
|
|
|
@ -505,7 +505,8 @@ public:
|
|||
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost) mrn_override;
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost) mrn_override;
|
||||
ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
|
||||
uint key_parts,
|
||||
|
@ -1057,6 +1058,7 @@ private:
|
|||
uint n_ranges,
|
||||
uint *bufsz,
|
||||
uint *flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate *cost);
|
||||
ha_rows storage_multi_range_read_info_const(uint keyno,
|
||||
RANGE_SEQ_IF *seq,
|
||||
|
@ -1064,6 +1066,7 @@ private:
|
|||
uint n_ranges,
|
||||
uint *bufsz,
|
||||
uint *flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate *cost);
|
||||
ha_rows wrapper_multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
#ifdef MRN_HANDLER_HAVE_MULTI_RANGE_READ_INFO_KEY_PARTS
|
||||
|
|
|
@ -2663,7 +2663,8 @@ int ha_myisam::multi_range_read_next(range_id_t *range_info)
|
|||
ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost)
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost)
|
||||
{
|
||||
/*
|
||||
This call is here because there is no location where this->table would
|
||||
|
@ -2672,7 +2673,7 @@ ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
|||
*/
|
||||
ds_mrr.init(this, table);
|
||||
return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
|
||||
flags, cost);
|
||||
flags, limit, cost);
|
||||
}
|
||||
|
||||
ha_rows ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
|
|
|
@ -165,7 +165,8 @@ public:
|
|||
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
|
||||
void *seq_init_param,
|
||||
uint n_ranges, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost);
|
||||
uint *flags, ha_rows limit,
|
||||
Cost_estimate *cost) override;
|
||||
ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
|
||||
uint key_parts, uint *bufsz,
|
||||
uint *flags, Cost_estimate *cost);
|
||||
|
|
|
@ -3151,6 +3151,7 @@ ha_rows ha_spider::multi_range_read_info_const(
|
|||
uint n_ranges,
|
||||
uint *bufsz,
|
||||
uint *flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate *cost
|
||||
)
|
||||
{
|
||||
|
@ -3190,6 +3191,7 @@ ha_rows ha_spider::multi_range_read_info_const(
|
|||
n_ranges,
|
||||
bufsz,
|
||||
flags,
|
||||
limit,
|
||||
cost
|
||||
);
|
||||
*flags &= ~HA_MRR_USE_DEFAULT_IMPL;
|
||||
|
|
|
@ -250,6 +250,7 @@ public:
|
|||
uint n_ranges,
|
||||
uint *bufsz,
|
||||
uint *flags,
|
||||
ha_rows limit,
|
||||
Cost_estimate *cost
|
||||
);
|
||||
ha_rows multi_range_read_info(
|
||||
|
|
Loading…
Reference in a new issue