summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc33
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;
}