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:
Monty 2022-09-23 14:48:13 +03:00 committed by Sergei Petrunia
commit 009db2288b
19 changed files with 154 additions and 85 deletions

View file

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

View file

@ -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