499
499
double read_time);
501
501
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
502
static int get_index_merge_params(PARAM *param, key_map& needed_reg,
503
SEL_IMERGE *imerge, double *read_time,
504
ha_rows* imerge_rows);
505
502
static double get_index_only_read_time(const PARAM* param, ha_rows records,
511
508
static void print_ror_scans_arr(TABLE *table, const char *msg,
512
509
struct st_ror_scan_info **start,
513
510
struct st_ror_scan_info **end);
514
static void print_rowid(byte* val, int len);
515
511
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
824
820
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
825
821
bool no_alloc, MEM_ROOT *parent_alloc)
826
:dont_free(0),error(0),free_file(0),in_range(0),cur_range(NULL),range(0)
822
:dont_free(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0)
6733
6728
start_key= &mrange_slot->start_key;
6734
6729
end_key= &mrange_slot->end_key;
6735
range= *(cur_range++);
6730
last_range= *(cur_range++);
6737
start_key->key= (const byte*) range->min_key;
6738
start_key->length= range->min_length;
6739
start_key->flag= ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
6740
(range->flag & EQ_RANGE) ?
6732
start_key->key= (const byte*) last_range->min_key;
6733
start_key->length= last_range->min_length;
6734
start_key->flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
6735
(last_range->flag & EQ_RANGE) ?
6741
6736
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
6742
end_key->key= (const byte*) range->max_key;
6743
end_key->length= range->max_length;
6737
end_key->key= (const byte*) last_range->max_key;
6738
end_key->length= last_range->max_length;
6745
6740
We use HA_READ_AFTER_KEY here because if we are reading on a key
6746
6741
prefix. We want to find all keys with this prefix.
6748
end_key->flag= (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6743
end_key->flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6749
6744
HA_READ_AFTER_KEY);
6751
mrange_slot->range_flag= range->flag;
6746
mrange_slot->range_flag= last_range->flag;
6754
6749
result= file->read_multi_range_first(&mrange, multi_range, count,
6812
6807
if (count == 0)
6814
6809
/* Ranges have already been used up before. None is left for read. */
6816
6811
DBUG_RETURN(HA_ERR_END_OF_FILE);
6818
range= *(cur_range++);
6813
last_range= *(cur_range++);
6820
start_key.key= (const byte*) range->min_key;
6821
start_key.length= min(range->min_length, prefix_length);
6822
start_key.flag= ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
6823
(range->flag & EQ_RANGE) ?
6815
start_key.key= (const byte*) last_range->min_key;
6816
start_key.length= min(last_range->min_length, prefix_length);
6817
start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
6818
(last_range->flag & EQ_RANGE) ?
6824
6819
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
6825
end_key.key= (const byte*) range->max_key;
6826
end_key.length= min(range->max_length, prefix_length);
6820
end_key.key= (const byte*) last_range->max_key;
6821
end_key.length= min(last_range->max_length, prefix_length);
6828
6823
We use READ_AFTER_KEY here because if we are reading on a key
6829
6824
prefix we want to find all keys with this prefix
6831
end_key.flag= (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6826
end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6832
6827
HA_READ_AFTER_KEY);
6834
result= file->read_range_first(range->min_length ? &start_key : 0,
6835
range->max_length ? &end_key : 0,
6836
test(range->flag & EQ_RANGE),
6829
result= file->read_range_first(last_range->min_length ? &start_key : 0,
6830
last_range->max_length ? &end_key : 0,
6831
test(last_range->flag & EQ_RANGE),
6838
if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
6839
range=0; // Stop searching
6833
if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
6834
last_range= 0; // Stop searching
6841
6836
if (result != HA_ERR_END_OF_FILE)
6842
6837
DBUG_RETURN(result);
6843
range=0; // No matching rows; go to next range
6838
last_range= 0; // No matching rows; go to next range
6859
6854
// Already read through key
6860
result= file->index_next_same(record, (byte*) range->min_key,
6855
result= file->index_next_same(record, (byte*) last_range->min_key,
6856
last_range->min_length);
6862
6857
if (result != HA_ERR_END_OF_FILE)
6863
6858
DBUG_RETURN(result);
6867
6862
if (count == 0)
6869
6864
/* Ranges have already been used up before. None is left for read. */
6871
6866
DBUG_RETURN(HA_ERR_END_OF_FILE);
6873
range= *(cur_range++);
6868
last_range= *(cur_range++);
6875
6870
result= file->index_read(record,
6876
(byte*) range->min_key,
6878
(ha_rkey_function)(range->flag ^ GEOM_FLAG));
6871
(byte*) last_range->min_key,
6872
last_range->min_length,
6873
(ha_rkey_function)(last_range->flag ^ GEOM_FLAG));
6879
6874
if (result != HA_ERR_KEY_NOT_FOUND)
6880
6875
DBUG_RETURN(result);
6881
range=0; // Not found, to next range
6876
last_range= 0; // Not found, to next range
6936
6931
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
6937
uint used_key_parts)
6932
uint used_key_parts_arg)
6938
6933
: QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
6940
6935
QUICK_RANGE *r;
6942
6937
QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
6943
QUICK_RANGE **last_range= pr + ranges.elements;
6944
for (; pr!=last_range; pr++)
6938
QUICK_RANGE **end_range= pr + ranges.elements;
6939
for (; pr!=end_range; pr++)
6945
6940
rev_ranges.push_front(*pr);
6947
6942
/* Remove EQ_RANGE flag for keys that are not using the full key */
6979
6974
{ // Already read through key
6980
result = ((range->flag & EQ_RANGE)
6981
? file->index_next_same(record, (byte*) range->min_key,
6982
range->min_length) :
6975
result = ((last_range->flag & EQ_RANGE)
6976
? file->index_next_same(record, (byte*) last_range->min_key,
6977
last_range->min_length) :
6983
6978
file->index_prev(record));
6990
6985
DBUG_RETURN(result);
6993
if (!(range=rev_it++))
6988
if (!(last_range= rev_it++))
6994
6989
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
6996
if (range->flag & NO_MAX_RANGE) // Read last record
6991
if (last_range->flag & NO_MAX_RANGE) // Read last record
6998
6993
int local_error;
6999
6994
if ((local_error=file->index_last(record)))
7000
6995
DBUG_RETURN(local_error); // Empty table
7001
if (cmp_prev(range) == 0)
6996
if (cmp_prev(last_range) == 0)
7002
6997
DBUG_RETURN(0);
7003
range=0; // No matching records; go to next range
6998
last_range= 0; // No match; go to next range
7007
if (range->flag & EQ_RANGE)
7002
if (last_range->flag & EQ_RANGE)
7009
result = file->index_read(record, (byte*) range->max_key,
7010
range->max_length, HA_READ_KEY_EXACT);
7004
result= file->index_read(record, (byte*) last_range->max_key,
7005
last_range->max_length, HA_READ_KEY_EXACT);
7014
DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
7015
result=file->index_read(record, (byte*) range->max_key,
7017
((range->flag & NEAR_MAX) ?
7018
HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV));
7009
DBUG_ASSERT(last_range->flag & NEAR_MAX ||
7010
range_reads_after_key(last_range));
7011
result=file->index_read(record, (byte*) last_range->max_key,
7012
last_range->max_length,
7013
((last_range->flag & NEAR_MAX) ?
7014
HA_READ_BEFORE_KEY :
7015
HA_READ_PREFIX_LAST_OR_PREV));
7022
7019
if (result != HA_ERR_KEY_NOT_FOUND)
7023
7020
DBUG_RETURN(result);
7024
range=0; // Not found, to next range
7021
last_range= 0; // Not found, to next range
7027
if (cmp_prev(range) == 0)
7024
if (cmp_prev(last_range) == 0)
7029
if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
7030
range = 0; // Stop searching
7026
if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7027
last_range= 0; // Stop searching
7031
7028
DBUG_RETURN(0); // Found key is in range
7033
range = 0; // To next range
7030
last_range= 0; // To next range
7507
7504
if ((join->tables != 1) || /* The query must reference one table. */
7508
7505
((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7509
7506
(!join->select_distinct)) ||
7510
(thd->lex->select_lex.olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7507
(join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7511
7508
DBUG_RETURN(NULL);
7512
7509
if (table->s->keys == 0) /* There are no indexes to use. */
7513
7510
DBUG_RETURN(NULL);
9517
static void print_rowid(byte* val, int len)
9521
fputc('\"', DBUG_FILE);
9522
for (pb= val; pb!= val + len; ++pb)
9523
fprintf(DBUG_FILE, "%c", *pb);
9524
fprintf(DBUG_FILE, "\", hex: ");
9526
for (pb= val; pb!= val + len; ++pb)
9527
fprintf(DBUG_FILE, "%x ", *pb);
9528
fputc('\n', DBUG_FILE);
9532
9514
void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
9516
/* purecov: begin inspected */
9534
9517
fprintf(DBUG_FILE, "%*squick range select, key %s, length: %d\n",
9535
9518
indent, "", head->key_info[index].name, max_used_key_length);
9539
9522
QUICK_RANGE *range;
9540
9523
QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
9541
QUICK_RANGE **last_range= pr + ranges.elements;
9542
for (; pr!=last_range; ++pr)
9524
QUICK_RANGE **end_range= pr + ranges.elements;
9525
for (; pr != end_range; ++pr)
9544
9527
fprintf(DBUG_FILE, "%*s", indent + 2, "");