Commit d1fa4332 authored by Igor Babaev's avatar Igor Babaev

Fixed calculation of rec_per_key elements for added components of the extended keys.

Slightly corrected the implementation of the function ha_innobase::read_time().
Changed the implementation of handler::keyread_time to make the cost of single key
index only look-ups dependent on the key entry length.
Corrected the index of the last possible components of an extended key in the
function best_access_path().
parent ec2828e4
...@@ -2146,11 +2146,12 @@ double handler::keyread_time(uint index, uint ranges, ha_rows rows) ...@@ -2146,11 +2146,12 @@ double handler::keyread_time(uint index, uint ranges, ha_rows rows)
performs a random seek, thus the cost is proportional to the number of performs a random seek, thus the cost is proportional to the number of
blocks read. This model does not take into account clustered indexes - blocks read. This model does not take into account clustered indexes -
engines that support that (e.g. InnoDB) may want to overwrite this method. engines that support that (e.g. InnoDB) may want to overwrite this method.
The model counts in the time to read index entries from cache.
*/ */
double keys_per_block= (stats.block_size/2.0/ ulong len= table->key_info[index].key_length + ref_length;
(table->key_info[index].key_length + double keys_per_block= (stats.block_size/2.0/len+1);
ref_length) + 1); return (rows + keys_per_block-1)/ keys_per_block +
return (rows + keys_per_block - 1)/ keys_per_block; len*rows/(stats.block_size+1)/TIME_FOR_COMPARE ;
} }
void **handler::ha_data(THD *thd) const void **handler::ha_data(THD *thd) const
......
...@@ -5193,7 +5193,8 @@ best_access_path(JOIN *join, ...@@ -5193,7 +5193,8 @@ best_access_path(JOIN *join,
} }
else else
{ {
if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1])) uint key_parts= table->actual_n_key_parts(keyinfo);
if (!(records=keyinfo->rec_per_key[key_parts-1]))
{ /* Prefer longer keys */ { /* Prefer longer keys */
records= records=
((double) s->records / (double) rec * ((double) s->records / (double) rec *
......
...@@ -5580,7 +5580,7 @@ bool st_table::is_filled_at_execution() ...@@ -5580,7 +5580,7 @@ bool st_table::is_filled_at_execution()
@return number of considered key components @return number of considered key components
*/ */
inline uint st_table::actual_n_key_parts(KEY *keyinfo) uint st_table::actual_n_key_parts(KEY *keyinfo)
{ {
return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ? return optimizer_flag(in_use, OPTIMIZER_SWITCH_EXTENDED_KEYS) ?
keyinfo->ext_key_parts : keyinfo->key_parts; keyinfo->ext_key_parts : keyinfo->key_parts;
......
...@@ -8230,11 +8230,6 @@ ha_innobase::read_time( ...@@ -8230,11 +8230,6 @@ ha_innobase::read_time(
return(handler::read_time(index, ranges, rows)); return(handler::read_time(index, ranges, rows));
} }
if (rows <= 2) {
return((double) rows);
}
/* Assume that the read time is proportional to the scan time for all /* Assume that the read time is proportional to the scan time for all
rows + at most one seek per range. */ rows + at most one seek per range. */
...@@ -8679,30 +8674,37 @@ ha_innobase::info_low( ...@@ -8679,30 +8674,37 @@ ha_innobase::info_low(
} }
KEY *key_info= table->key_info+i; KEY *key_info= table->key_info+i;
key_part_map ext_key_part_map= key_info->ext_key_part_map; key_part_map ext_key_part_map=
key_info->ext_key_part_map;
if (key_info->key_parts != key_info->ext_key_parts) { if (key_info->key_parts != key_info->ext_key_parts) {
KEY *pk_key_info= key_info+ KEY *pk_key_info= key_info+
table->s->primary_key; table->s->primary_key;
uint k= key_info->key_parts; uint k = key_info->key_parts;
ha_rows k_rec_per_key = rec_per_key;
for (j = 0; j < pk_key_info->key_parts; j++) { uint pk_parts = pk_key_info->key_parts;
index= innobase_get_index(
table->s->primary_key);
for (j = 0; j < pk_parts; j++) {
if (ext_key_part_map & 1<<j) { if (ext_key_part_map & 1<<j) {
index = innobase_get_index(
table->s->primary_key);
rec_per_key = rec_per_key =
innodb_rec_per_key(index, innodb_rec_per_key(index,
j, stats.records); j, stats.records);
if (rec_per_key == 0) { if (rec_per_key == 0) {
rec_per_key = 1; rec_per_key = 1;
} }
else if (rec_per_key > 1) {
rec_per_key =
k_rec_per_key *
(double)rec_per_key /
n_rows;
}
key_info->rec_per_key[k++]= key_info->rec_per_key[k++]=
rec_per_key >= ~(ulong) 0 ? rec_per_key >= ~(ulong) 0 ?
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment