diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index 4d53c3e8424..02753f24812 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3208,20 +3208,45 @@ LEX_CSTRING *handler::engine_name() by index 'keyno' of one range containing 'rows' key entries. If ranges == 0 then the function returns only the cost of copying those key entries into the engine buffers. + + This function doesn't take in account into copying the key to record + (INDEX_COPY_COST) or comparing the key to the where clause (TIME_FOR_COMPARE) */ double handler::keyread_time(uint index, uint ranges, ha_rows rows) { + size_t len; + double cost; DBUG_ASSERT(ranges == 0 || ranges == 1); - size_t len= table->key_info[index].key_length + ref_length; + len= table->key_info[index].key_length + ref_length; if (table->file->is_clustering_key(index)) len= table->s->stored_rec_length; - double cost= (double)rows*len/(stats.block_size+1)*IDX_BLOCK_COPY_COST; + + cost= ((double)rows*len/(stats.block_size+1)*INDEX_BLOCK_COPY_COST); + /* + We divide the cost with optimizer_cache_cost as ha_keyread_time() + and ha_key_scan_time() will multiply the result value with + optimizer_cache_cost and we want to keep the above 'memory operation' + cost unaffected by this multiplication. + */ + cost/= optimizer_cache_cost; if (ranges) { uint keys_per_block= (uint) (stats.block_size*3/4/len+1); - ulonglong blocks= (rows+ keys_per_block- 1)/keys_per_block; - cost+= blocks; + /* + We let the cost grow slowly in proportion to number of rows to + promote indexes with less rows. + We do not calculate exact number of block reads as then index + only reads will be more costly than normal reads, especially + compared to InnoDB clustered keys. + + INDEX_LOOKUP_COST is the cost of finding the first key in the + range. Finding the next key is usually a fast operation so we + don't count it here, it is taken into account in + ha_keyread_and_copy_time() + */ + cost+= (((double) (rows / keys_per_block) + INDEX_LOOKUP_COST) * + avg_io_cost()); } return cost; } |