MySQL 26.7.0
Source Code Documentation
cost_model.h
Go to the documentation of this file.
1/* Copyright (c) 2020, 2026, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef SQL_JOIN_OPTIMIZER_COST_MODEL_H_
25#define SQL_JOIN_OPTIMIZER_COST_MODEL_H_
26
27#include <algorithm> // std::clamp
28#include <cmath> // std::log2, std::max
29#include <span>
30
31#include "my_base.h"
32#include "my_bitmap.h" // bitmap_bits_set
33
37#include "sql/mem_root_array.h"
38#include "sql/table.h"
39
40struct AccessPath;
42class Item;
43class Query_block;
44class THD;
45
46/**
47 When we make cost estimates, we use this as the maximal length the
48 values we get from evaluating an Item (in bytes). Actual values of
49 e.g. blobs may be much longer, but even so we use this as an upper
50 limit when doing cost calculations. (For context, @see Item#max_length .)
51*/
52constexpr size_t kMaxItemLengthEstimate = 4096;
53
54/// A fallback cardinality estimate that is used in case the storage engine
55/// cannot provide one (like for table functions). It's a fairly arbitrary
56/// non-zero value.
58
59/**
60 We model the IO cost for InnoDB tables with the DYNAMIC row format. For
61 other storage engines the IO cost is currently set to zero. For other
62 InnoDB row formats, the model may not be a good fit.
63
64 We only count the cost of accessing the leaf pages of indexes (clustered
65 or unclustered)that are not already in the buffer pool. For tables/indexes
66 that are (estimated to be) fully cached we get an IO cost of zero.
67 Tables that are small relative to the buffer pool are assumed to be fully
68 cached (all pages are in the buffer pool).
69 The only operations for which we count IO cost are random and sequential
70 page reads.
71
72 The cost of a disk IO operation is modeled as an affine function:
73
74 io_cost = kIOStartCost + no_of_bytes * kIOByteCost
75
76 Note that the granularity of no_of_bytes is the storage engine page size.
77 The values used here are derived from measurements in a cloud setting.
78 This means that they may be wrong in another context, such as when
79 running against a local SSD. Cloud measurements may also give inconsistent
80 results due to heterogeneous cloud hardware, and the impact of activity
81 in other cloud VMs.
82 Ideally we should be able to configure these parameters, or even set them
83 dynamically based on observed behavior.
84*/
85constexpr double kIOStartCost{937.0};
86
87/// The additional cost of reading an extra byte from disk.
88constexpr double kIOByteCost{0.0549};
89
90/// This is the estimated fraction of an (innodb) block that is in use
91/// (i.e. not free for future inserts).
92constexpr double kBlockFillFactor{0.75};
93
94/// See EstimateFilterCost.
95struct FilterCost {
96 /// Cost of evaluating the filter for all rows if subqueries are not
97 /// materialized. (Note that this includes the contribution from
98 /// init_cost_if_not_materialized.)
100
101 /// Initial cost before the filter can be applied for the first time.
102 /// Typically the cost of executing 'independent subquery' in queries like:
103 /// "SELECT * FROM tab WHERE field = <independent subquery>".
104 /// (That corresponds to the Item_singlerow_subselect class.)
106
107 /// Cost of evaluating the filter for all rows if all subqueries in
108 /// it have been materialized beforehand. If there are no subqueries
109 /// in the condition, equals cost_if_not_materialized.
111
112 /// Cost of materializing all subqueries present in the filter.
113 /// If there are no subqueries in the condition, equals zero.
115};
116
117/// Used internally by EstimateFilterCost() only.
118void AddCost(THD *thd, const ContainedSubquery &subquery, double num_rows,
119 FilterCost *cost);
120
121/**
122 Estimate the cost of evaluating “condition”, “num_rows” times.
123 This is a fairly rudimentary estimation, _but_ it includes the cost
124 of any subqueries that may be present and that need evaluation.
125 */
126FilterCost EstimateFilterCost(THD *thd, double num_rows, Item *condition,
127 const Query_block *outer_query_block);
128
129/**
130 A cheaper overload of EstimateFilterCost() that assumes that all
131 contained subqueries have already been extracted (ie., it skips the
132 walking, which can be fairly expensive). This data is typically
133 computed by FindContainedSubqueries().
134 */
136 THD *thd, double num_rows,
137 const Mem_root_array<ContainedSubquery> &contained_subqueries) {
138 FilterCost cost;
141
142 for (const ContainedSubquery &subquery : contained_subqueries) {
143 AddCost(thd, subquery, num_rows, &cost);
144 }
145 return cost;
146}
147
148/**
149 Estimate costs and output rows for a SORT AccessPath.
150 @param thd Current thread.
151 @param path the AccessPath.
152 @param distinct_rows An estimate of the number of distinct rows, if
153 remove_duplicates==true and we have an estimate already.
154*/
156 double distinct_rows = kUnknownRowCount);
157
159
160/// Array of aggregation terms.
161using TermArray = std::span<const Item *const>;
162
163/**
164 Estimate the number of rows with a distinct combination of values for
165 'terms'. @see EstimateDistinctRowsFromStatistics for additional details.
166 @param thd The current thread.
167 @param child_rows The number of input rows.
168 @param terms The terms for which we estimate the number of unique
169 combinations.
170 @returns The estimated number of output rows.
171*/
172double EstimateDistinctRows(THD *thd, double child_rows, TermArray terms);
173/**
174 Estimate costs and result row count for an aggregate operation.
175 @param[in,out] thd The current thread.
176 @param[in,out] path The AGGREGATE path.
177 @param[in] query_block The Query_block to which 'path' belongs.
178 */
180 const Query_block *query_block);
181
182/**
183 Estimate costs and result row count for a skip scan operation.
184 @param[in] table The table which is to be scanned
185 @param[in] key_idx The location of the index to be scanned
186 @param[in] num_subrange_scans Number of subrange scans to be executed
187 @param[in] records Number of rows to be scanned
188 @retval Calculated cost value
189 */
190double EstimateSkipScanCost(TABLE *table, uint key_idx, uint num_subrange_scans,
191 ha_rows records);
192
193/**
194 Estimate costs for a group skip scan operation.
195 @param[in] table The table which is to be scanned
196 @param[in] key_idx The location of the index to be scanned
197 @param[in] num_groups Number of GROUP BY groups to be scanned
198 @param[in] has_max True if the query contains MAX(), else false
199 @retval Calculated cost value
200 */
201double EstimateGroupSkipScanCost(TABLE *table, uint key_idx, uint num_groups,
202 bool has_max);
203
206
207/// Estimate the costs and row count for a STREAM AccessPath.
209
210/**
211 Estimate the costs and row count for a WINDOW AccessPath. As described in
212 @see AccessPath::m_init_cost, the cost to read k out of N rows would be
213 init_cost + (k/N) * (cost - init_cost).
214*/
216
217/// Estimate the costs and row count for a Temp table Aggregate AccessPath.
219 const Query_block *query_block);
220
221/// Estimate the costs and row count for a WINDOW AccessPath.
223
224/**
225 Estimate the fan out for a left semijoin or a left antijoin. The fan out
226 is defined as the number of result rows, divided by the number of input
227 rows from the left hand relation. For a semijoin, J1:
228
229 SELECT ... FROM t1 WHERE EXISTS (SELECT ... FROM t2 WHERE predicate)
230
231 we know that the fan out of the corresponding inner join J2:
232
233 SELECT ... FROM t1, t2 WHERE predicate
234
235 is: F(J2) = CARD(t2) * SELECTIVITY(predicate) , where CARD(t2)=right_rows,
236 and SELECTIVITY(predicate)=edge.selectivity. If 'predicate' is a
237 deterministic function of t1 and t2 rows, then J1 is equivalent to an inner
238 join J3:
239
240 SELECT ... FROM t1 JOIN (SELECT DISTINCT f1,..fn FROM t2) d ON predicate
241
242 where f1,..fn are those fields from t2 that appear in the predicate.
243
244 Then F(J1) = F(J3) = F(J2) * CARD(d) / CARD(t2)
245 = CARD(d) * SELECTIVITY(predicate).
246
247 This function therefore collects f1..fn and estimates CARD(d). As a special
248 case, 'predicate' may be independent of t2. The query is then equivalent to:
249
250 SELECT ... FROM t1 WHERE predicate AND (SELECT COUNT(*) FROM t2) > 0
251
252 The fan out is then the selectivity of 'predicate' multiplied by the
253 probability of t2 having at least one row.
254
255 @param thd The current thread.
256 @param right_rows The number of input rows from the right hand relation.
257 @param edge Join edge.
258 @returns fan out.
259 */
260double EstimateSemijoinFanOut(THD *thd, double right_rows,
261 const JoinPredicate &edge);
262
263/**
264 Estimate the number of output rows from joining two relations.
265 @param thd The current thread.
266 @param left_rows Number of rows in the left hand relation.
267 @param right_rows Number of rows in the right hand relation.
268 @param edge The join between the two relations.
269*/
270inline double FindOutputRowsForJoin(THD *thd, double left_rows,
271 double right_rows,
272 const JoinPredicate *edge) {
273 switch (edge->expr->type) {
275 // For outer joins, every outer row produces at least one row (if none
276 // are matching, we get a NULL-complemented row).
277 // Note that this can cause inconsistent row counts; see bug #33550360
278 // and/or JoinHypergraph::has_reordered_left_joins.
279 return left_rows * std::max(right_rows * edge->selectivity, 1.0);
280
282 return left_rows * EstimateSemijoinFanOut(thd, right_rows, *edge);
283
285 // Antijoin are estimated as simply the opposite of semijoin (see above),
286 // but wrongly estimating 0 rows (or, of course, a negative amount) could
287 // be really bad, so we assume at least 10% coming out as a fudge factor.
288 // It's better to estimate too high than too low here.
289 return left_rows *
290 std::max(1.0 - EstimateSemijoinFanOut(thd, right_rows, *edge),
291 0.1);
292
295 return left_rows * right_rows * edge->selectivity;
296
297 case RelationalExpression::FULL_OUTER_JOIN: // Not implemented.
298 case RelationalExpression::MULTI_INNER_JOIN: // Should not appear here.
299 case RelationalExpression::TABLE: // Should not appear here.
300 assert(false);
301 return 0;
302
303 default:
304 assert(false);
305 return 0;
306 }
307}
308
309/**
310 Determines whether a given key on a table is both clustered and primary.
311
312 @param table The table to which the index belongs.
313 @param key_idx The position of the key in table->key_info[].
314
315 @return True if the key is clustered and primary, false otherwise.
316*/
317inline bool IsClusteredPrimaryKey(const TABLE *table, unsigned key_idx) {
318 if (table->s->is_missing_primary_key()) return false;
319 return key_idx == table->s->primary_key &&
320 table->file->primary_key_is_clustered();
321}
322
323/// The minimum number of bytes to return for row length estimates. This is
324/// mostly to guard against returning estimates of zero, which may or may not
325/// actually be able to happen in practice.
326constexpr unsigned kMinEstimatedBytesPerRow = 8;
327
328/// The maximum number of bytes to return for row length estimates. The current
329/// value of this constant is set to cover a wide range of row sizes and should
330/// capture the most common row lengths in bytes. We place an upper limit on the
331/// estimates since we have performed our calibration within this range, and we
332/// would like to prevent cost estimates from running away in case the
333/// underlying statistics are off in some instances. In such cases we prefer
334/// capping the resulting estimate. As a reasonable upper limit we use half the
335/// default InnoDB page size of 2^14 = 16384 bytes.
336constexpr unsigned kMaxEstimatedBytesPerRow = 8 * 1024;
337
338/**
339 This struct represents the number of bytes we expect to read for a table row.
340 Note that the split between b-tree and overflow pages is specific to InnoDB
341 and may not be a good fit for other storage engines. Ideally we should
342 calculate row size and IO-cost in the handler, in a way that is specific to
343 each particular storage engine.
344 When using the DYNAMIC row format, an InnoDB B-tree record cannot be bigger
345 than about half a page. (The default page size is 16KB). Above that, the
346 longest fields are stored in separate overflow pages.
347*/
349 /**
350 The number of bytes read from the B-tree record. This also includes those
351 fields that were not in the projection.
352 */
354
355 /**
356 The number of bytes read from overflow pages. This is the combined size
357 of those long variable-sized fields that are in the projection but stored
358 in overflow pages.
359 */
361
362 /*
363 The probability of reading from an overflow page (i.e. an estimate
364 of the probability that at least one of the columns in the
365 projection overflows).
366 */
368};
369
370/**
371 Calculate an estimate of the row size of the read set of 'table'.
372*/
373int64_t CalculateReadSetWidth(const TABLE *table);
374
375/**
376 Estimate the average number of bytes that we need to read from the
377 storage engine when reading a row from 'table'. This is the size of
378 the (b-tree) record and the overflow pages of any field that is
379 part of the projection. This is similar to what EstimateBytesPerRowTable()
380 does, but this function is intended to do a more accurate but also more
381 expensive calculation for tables with potentially large rows (i.e. tables
382 with BLOBs or large VARCHAR fields).
383
384 Note that this function tailored for InnoDB (and also for the
385 DYNAMIC row format of InnoDB). At some point we may want to move
386 this logic to the handler, so that we can customize it for other
387 engines as well.
388
389 @param table The target table
390 @returns The estimated row size.
391*/
393
394/// We clamp the block size to lie in the interval between the max and min
395/// allowed block size for InnoDB (2^12 to 2^16). Ideally we would have a
396/// guarantee that stats.block_size has a reasonable value (across all storage
397/// engines, types of tables, state of statistics), but in the absence of such
398/// a guarantee we clamp to the values for the InnoDB storage engine since the
399/// cost model has been calibrated for these values.
400inline unsigned ClampedBlockSize(const TABLE *table) {
401 constexpr unsigned kMinEstimatedBlockSize = 4096;
402 constexpr unsigned kMaxEstimatedBlockSize = 65536;
403 return std::clamp(table->file->stats.block_size, kMinEstimatedBlockSize,
404 kMaxEstimatedBlockSize);
405}
406
407/**
408 Estimates the number of bytes that MySQL must process when reading a row from
409 a table, independently of the size of the read set.
410
411 @param table The table to produce an estimate for.
412
413 @returns The estimated row size.
414
415 @note There are two different relevant concepts of bytes per row:
416
417 1. The bytes per row on the storage engine side.
418 2. The bytes per row on the server side.
419
420 One the storage engine side, for InnoDB at least, we compute
421 stats.mean_rec_length as the size of the data file divided by the number of
422 rows in the table.
423
424 On the server side we are interested in the size of the MySQL representation
425 in bytes. This could be a more accurate statistic when determining the CPU
426 cost of processing a row (i.e., it does not matter very much if InnoDB pages
427 are only half-full). As an approximation to the size of a row in bytes on the
428 server side we use the length of the record buffer for rows that should
429 not exceed the maximal size of an InnoDB B-tree record. (Otherwise, we call
430 EstimateBytesPerRowWideTable() to make the estimate).
431
432 Note that when the table fits in a single page stats.mean_rec_length
433 will tend to overestimate the record length since it is computed as
434 stats.data_file_length / stats.records and the data file length is
435 at least a full page which defaults to 16384 bytes (for InnoDB at
436 least). We may then get a better estimate from table->s->rec_buff_length.
437*/
439 int64_t max_bytes{0};
440
441 for (uint i = 0; i < table->s->fields; i++) {
442 // max_data_length() is the maximal size (in bytes) of this field.
443 max_bytes += table->field[i]->max_data_length();
444 }
445
446 if (max_bytes < ClampedBlockSize(table) / 2) {
447 // The row should fit in a b-tree record.
448 return {.record_bytes =
449 std::clamp(table->s->rec_buff_length, kMinEstimatedBytesPerRow,
451 .overflow_bytes = 0,
452 .overflow_probability = 0.0};
453 }
454
455 // Make a more sophisticated estimate for tables that may have very
456 // large rows.
458}
459
460/**
461 Estimates the number of bytes that MySQL must process when reading a row from
462 a secondary index, independently of the size of the read set.
463
464 @param table The table to which the index belongs.
465 @param key_idx The position of the key in table->key_info[].
466
467 @return The estimated number of bytes per row in the index.
468*/
469inline unsigned EstimateBytesPerRowIndex(const TABLE *table, unsigned key_idx) {
470 // key_length should correspond to the length of the field(s) of the key in
471 // bytes and ref_length is the length of the field(s) of the primary key in
472 // bytes. Secondary indexes (in InnoDB) contain a copy of the value of the
473 // primary key associated with a given row, in order to make it possible to
474 // retrieve the corresponding row from the primary index in case we use a
475 // non-covering index operation.
476 unsigned estimate =
477 table->key_info[key_idx].key_length + table->file->ref_length;
478 return std::clamp(estimate, kMinEstimatedBytesPerRow,
480}
481
482/**
483 Estimates the height of a B-tree index.
484
485 We estimate the height of the index to be the smallest positive integer h such
486 that table_records <= (1 + records_per_page)^h.
487
488 This function supports both clustered primary indexes and secondary indexes.
489 Secondary indexes will tend to have more records per page compared to primary
490 clustered indexes and as a consequence they will tend to be shorter.
491
492 @param table The table to which the index belongs.
493 @param key_idx The position of the key in table->key_info[].
494
495 @return The estimated height of the index.
496*/
497inline int IndexHeight(const TABLE *table, unsigned key_idx) {
498 unsigned block_size = ClampedBlockSize(table);
499 unsigned bytes_per_row = IsClusteredPrimaryKey(table, key_idx)
500 ? table->bytes_per_row()->record_bytes
502
503 // Ideally we should always have that block_size >= bytes_per_row, but since
504 // the storage engine and MySQL row formats differ, this is not always the
505 // case. Therefore we manually ensure that records_per_page >= 1.0.
506 double records_per_page =
507 std::max(1.0, static_cast<double>(block_size) / bytes_per_row);
508
509 // Computing the height using a while loop instead of using std::log turns out
510 // to be about 5 times faster in microbenchmarks when the measurement is made
511 // using a somewhat realistic and representative set of values for the number
512 // of records per page and the number of records in the table. In the worst
513 // case, if the B-tree contains only a single record per page, the table would
514 // have to contain 2^30 pages (corresponding to more than 16 terabytes of
515 // data) for this loop to run 30 times. A B-tree with 1 billion records and
516 // 100 records per page only uses 4 iterations of the loop (the height is 5).
517 int height = 1;
518 double r = 1.0 + records_per_page;
519 while (r < table->file->stats.records) {
520 r = r * (1.0 + records_per_page);
521 height += 1;
522 }
523 return height;
524}
525
526/// Calculate the IO-cost of reading 'num_rows' rows from 'table'.
527double TableAccessIOCost(const TABLE *table, double num_rows,
528 BytesPerTableRow row_size);
529
530/// Calculate the IO-cost of doing a lookup on index 'key_idx' on 'table'
531/// and then read 'num_rows' rows.
532double CoveringIndexAccessIOCost(const TABLE *table, unsigned key_idx,
533 double num_rows);
534
535/**
536 Computes the expected cost of reading a number of rows. The cost model takes
537 into account the number of fields that is being read from the row and the
538 width of the row in bytes. Both RowReadCostTable() and RowReadCostIndex() call
539 this function and thus use the same cost model.
540
541 @param num_rows The (expected) number of rows to read.
542 @param fields_read_per_row The number of fields to read per row.
543 @param bytes_per_row The total length of the row to be processed (including
544 fields that are not read) in bytes.
545
546 @returns The expected cost of reading num_rows.
547
548 @note It is important that this function be robust to fractional row
549 estimates. For example, if we index nested loop join two primary key columns
550 and the inner table is smaller than the outer table, we should see that
551 num_rows for the inner index lookup is less than one. In this case it is
552 important that we return the expected cost of the operation. For example, if
553 we only expect to read 0.1 rows the cost should be 0.1 of the cost of reading
554 one row (we are working with a linear cost model, so we only have to take the
555 expected number of rows into account, and not the complete distribution).
556*/
557inline double RowReadCost(double num_rows, double fields_read_per_row,
558 double bytes_per_row) {
559 return (kReadOneRowCost + kReadOneFieldCost * fields_read_per_row +
560 kReadOneByteCost * bytes_per_row) *
561 num_rows;
562}
563
564/**
565 Computes the cost of reading a number of rows from a table.
566 @see ReadRowCost() for further details.
567
568 @param table The table to read from.
569 @param num_rows The (expected) number of rows to read.
570
571 @returns The cost of reading num_rows.
572*/
573inline double RowReadCostTable(const TABLE *table, double num_rows) {
574 double fields_read_per_row = bitmap_bits_set(table->read_set);
575 const BytesPerTableRow &bytes_per_row = *table->bytes_per_row();
576 return RowReadCost(
577 num_rows, fields_read_per_row,
578 bytes_per_row.record_bytes + bytes_per_row.overflow_bytes) +
579 TableAccessIOCost(table, num_rows, bytes_per_row);
580}
581
582/**
583 Computes the cost of reading a number of rows from an index.
584 @see ReadRowCost() for further details.
585
586 @param table The table to which the index belongs.
587 @param key_idx The position of the key in table->key_info[].
588 @param num_rows The (expected) number of rows to read.
589
590 @returns The cost of reading num_rows.
591*/
592inline double RowReadCostIndex(const TABLE *table, unsigned key_idx,
593 double num_rows) {
594 if (IsClusteredPrimaryKey(table, key_idx)) {
595 return RowReadCostTable(table, num_rows);
596 }
597 // Assume we read two fields from the index record if it is not covering. The
598 // exact assumption here is not very important as the cost should be dominated
599 // by the additional lookup into the primary index.
600 constexpr double kDefaultFieldsReadFromCoveringIndex = 2;
601 double fields_read_per_row = table->covering_keys.is_set(key_idx)
602 ? bitmap_bits_set(table->read_set)
603 : kDefaultFieldsReadFromCoveringIndex;
604
605 double bytes_per_row = EstimateBytesPerRowIndex(table, key_idx);
606 return RowReadCost(num_rows, fields_read_per_row, bytes_per_row) +
607 CoveringIndexAccessIOCost(table, key_idx, num_rows);
608}
609
610/**
611 Estimates the cost of a full table scan. Primarily used to assign a cost to
612 the TABLE_SCAN access path.
613
614 @param table The table to estimate cost for.
615
616 @returns The cost of scanning the table.
617*/
618inline double EstimateTableScanCost(const TABLE *table) {
619 return RowReadCostTable(table, table->file->stats.records);
620}
621
622/**
623 Estimates the cost of an index lookup.
624
625 @param table The table to which the index belongs.
626 @param key_idx The position of the key in table->key_info[].
627
628 @return The estimated cost of an index lookup.
629
630 @note The model "cost ~ index_height" works well when the Adaptive Hash Index
631 (AHI) is disabled. The AHI essentially works as a dynamic cache for the most
632 frequently accessed index pages that sits on top of the B-tree. With AHI
633 enabled the cost of random lookups does not appear to be predictable using
634 standard explanatory variables such as index height or the logarithm of the
635 number of rows in the index. The performance of AHI will also be dependent on
636 the access pattern, so it is fundamentally difficult to create an accurate
637 model. However, our calibration experiments reveal two things that hold true
638 both with and without AHI enabled:
639
640 1. Index lookups usually take 1-3 microseconds. The height of a B-tree grows
641 very slowly (proportional to log(N)/log(R) for tables with N rows and R
642 records per page), making it near-constant in the common case where tables
643 have many records per page, even without AHI.
644
645 2. Random lookups in large indexes tend to be slower. A random access pattern
646 will cause more cache misses, both for regular hardware caching and AHI. In
647 addition, for a larger B-tree only the top levels fit in cache and we will
648 invariably see a few cache misses with random accesses.
649
650 We model the cost of index lookups by interpolating between a model with
651 constant cost and a model that depends entirely on the height of the index.
652 The constants are based on calibration experiments with and without AHI.
653
654 Another factor that is important when calibrating the cost of index lookups is
655 whether we are interested in the average cost when performing many lookups
656 such as when performing an index nested loop join or scanning along a
657 secondary non-covering index and lookup into the primary index, or the cost of
658 a single lookup such as a point select that uses an index. From our
659 measurements we see that the average running time of an index lookup can
660 easily be a factor ~5x faster when performing thousands of successive lookups
661 compared to just one. This is likely due to hardware caching effects. Since
662 getting the cost right in the case when we perform many lookups is typically
663 more important, we have opted to calibrate costs based on operations that
664 perform many lookups.
665
666 For adding IO costs to this model (future work) we probably want to assume
667 that we only fetch a single page when performing an index lookup, as
668 everything but leaf pages will tend to be cached, at least when performing
669 many index lookups in a query plan, which is exactly the case where it is
670 important to get costs right.
671*/
672inline double IndexLookupCost(const TABLE *table, unsigned key_idx) {
673 assert(key_idx < table->s->keys);
674 double cost_with_ahi = kIndexLookupFixedCost;
675 double cost_without_ahi = kIndexLookupPageCost * IndexHeight(table, key_idx);
676 return 0.5 * (cost_with_ahi + cost_without_ahi);
677}
678
679/// Type of range scan operation.
680enum class RangeScanType : char {
681 /// Using the MRR optimization.
683
684 /// Plain range scan, without the MRR optimization.
686};
687
688/**
689 Estimates the cost of an index range scan.
690
691 The cost model for index range scans accounts for the index lookup cost as
692 well as the cost of reading rows. Both index scans and ref accesses can be
693 viewed as special cases of index range scans, so the cost functions for those
694 operations call this function under the hood.
695
696 @note In the future this function should be extended to account for IO cost.
697
698 @param table The table to which the index belongs.
699 @param key_idx The position of the key in table->key_info[].
700 @param scan_type Whether this an MRR or a regular index range scan.
701 @param num_ranges The number of ranges.
702 @param num_output_rows The estimated expected number of output rows.
703
704 @returns The estimated cost of the index range scan operation.
705*/
706double EstimateIndexRangeScanCost(const TABLE *table, unsigned key_idx,
707 RangeScanType scan_type, double num_ranges,
708 double num_output_rows);
709
710/**
711 Estimates the cost of an index scan. An index scan scans all rows in the
712 table along the supplied index.
713
714 @param table The table to which the index belongs.
715 @param key_idx The position of the key in table->key_info[].
716
717 @returns The estimated cost of the index scan.
718*/
719inline double EstimateIndexScanCost(const TABLE *table, unsigned key_idx) {
720 if (IsClusteredPrimaryKey(table, key_idx)) {
722 }
723
725 1.0, table->file->stats.records);
726}
727
728/**
729 Estimates the cost of an index lookup (ref access).
730
731 @param table The table to which the index belongs.
732 @param key_idx The position of the key in table->key_info[].
733 @param num_output_rows The estimated number of output rows.
734
735 @returns The estimated cost of the index scan.
736*/
737inline double EstimateRefAccessCost(const TABLE *table, unsigned key_idx,
738 double num_output_rows) {
739 // We want the optimizer to prefer ref acccesses to range scans when they both
740 // have the same cost. This is particularly important for the EQ_REF access
741 // path (index lookups with at most one matching row) since the EQ_REF
742 // iterator uses caching to improve performance.
743 constexpr double kRefAccessCostDiscount = 0.05;
744 return (1.0 - kRefAccessCostDiscount) *
746 1.0, num_output_rows);
747}
748
749/**
750 Estimates the one-time cost of building a B-tree index on a materialized
751 temporary table. Uses the same cost model as EstimateSortCost():
752 an O(N) per-row insertion component plus an O(N * log2(N)) comparison
753 component.
754
755 @param num_rows Number of rows in the materialized table.
756
757 @returns The estimated cost of building the index.
758*/
759inline double EstimateIndexBuildCost(double num_rows) {
760 if (num_rows <= 1.0) return 0.0;
761 // Per-row cost of inserting into the B-tree (memory allocation, copying
762 // row data into index nodes). Analogous to kSortOneRowCost in sort.
763 const double insertion_cost = kSortOneRowCost * num_rows;
764 // O(N log N) cost of key comparisons to maintain B-tree ordering.
765 const double comparison_cost =
766 kSortComparisonCost * num_rows * std::log2(num_rows);
767 return insertion_cost + comparison_cost;
768}
769
770/**
771 Input to HashJoinCost, for calculating the cost of a hash join.
772*/
773struct HashJoinMetrics final {
774 /// The number of rows in the 'build' input.
776 /// The average size of rows in the 'build' input (in bytes).
778 /// The size of the join key, in bytes.
779 double key_size;
780 /// The number of rows in the 'probe' input.
782 /// The average size of rows in the 'probe' input (in bytes).
784 /// The number of rows in the result set.
786};
787
788/** This class represents the cost of a hash join (excluding the cost
789 of sub-paths).
790*/
791class HashJoinCost final {
792 public:
794 bool allow_spill_to_disk = true);
795
798 }
799
800 double init_cost() const { return m_init_cost; }
801
802 double cost() const { return m_cost; }
803
804 /// The number of times the probe input must be scanned. Greater than 1
805 /// when the build input does not fit in the join buffer and we need
806 /// multiple passes (with hash table refills).
807 double probe_iterations() const { return m_probe_iterations; }
808
809 /// Estimated probability that the build input overflows one join
810 /// buffer. Unlike spill_to_disk_probability(), this is independent of
811 /// allow_spill_to_disk: a no-spill plan with overflow_probability()>0
812 /// will refill the hash table rather than write chunk files, but the
813 /// in-memory buffer is still not reusable across re-Init() in that case.
815
816 private:
817 /// The probability (range [0.0, 1.0]) of needing spill to disk.
819 /// The probability (range [0.0, 1.0]) that the build input overflows
820 /// one join buffer, regardless of whether spill-to-disk is allowed.
822 /// The cost of preparing to produce the first result row.
824 /// The cost of the hash join.
825 double m_cost;
826 /// The number of iterations over the probe input. Used by
827 /// ProposeHashJoin() to account for probe re-scanning cost.
829};
830
831#endif // SQL_JOIN_OPTIMIZER_COST_MODEL_H_
constexpr double kUnknownRowCount
To indicate that a row estimate is not yet made.
Definition: access_path.h:201
This class represents the cost of a hash join (excluding the cost of sub-paths).
Definition: cost_model.h:791
double m_probe_iterations
The number of iterations over the probe input.
Definition: cost_model.h:828
double m_init_cost
The cost of preparing to produce the first result row.
Definition: cost_model.h:823
double overflow_probability() const
Estimated probability that the build input overflows one join buffer.
Definition: cost_model.h:814
double m_overflow_probability
The probability (range [0.0, 1.0]) that the build input overflows one join buffer,...
Definition: cost_model.h:821
double spill_to_disk_probability() const
Definition: cost_model.h:796
double init_cost() const
Definition: cost_model.h:800
double m_spill_to_disk_probability
The probability (range [0.0, 1.0]) of needing spill to disk.
Definition: cost_model.h:818
double probe_iterations() const
The number of times the probe input must be scanned.
Definition: cost_model.h:807
HashJoinCost(THD *thd, const HashJoinMetrics &metrics, bool allow_spill_to_disk=true)
Definition: cost_model.cc:1817
double cost() const
Definition: cost_model.h:802
double m_cost
The cost of the hash join.
Definition: cost_model.h:825
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:929
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:432
This class represents a query block, aka a query specification, which is a query consisting of a SELE...
Definition: sql_lex.h:1198
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Hypergraph optimizer cost constants.
constexpr double kReadOneFieldCost
Cost of per field in the read set.
Definition: cost_constants.h:85
constexpr double kApplyOneFilterCost
Cost of evaluating one filter on one row.
Definition: cost_constants.h:117
constexpr double kReadOneRowCost
Fixed cost of reading a row from the storage engine into the record buffer.
Definition: cost_constants.h:81
constexpr double kIndexLookupPageCost
The cost per page that is visited when performing an index lookup in an InnoDB B-tree.
Definition: cost_constants.h:129
constexpr double kSortComparisonCost
Cost per comparison during sorting.
Definition: cost_constants.h:150
constexpr double kIndexLookupFixedCost
Fixed cost of an index lookup when AHI is enabled (default).
Definition: cost_constants.h:132
constexpr double kSortOneRowCost
Fixed overhead per input row when sorting.
Definition: cost_constants.h:144
constexpr double kReadOneByteCost
Overhead per byte when reading a row.
Definition: cost_constants.h:95
double RowReadCost(double num_rows, double fields_read_per_row, double bytes_per_row)
Computes the expected cost of reading a number of rows.
Definition: cost_model.h:557
constexpr ha_rows kRowEstimateFallback
A fallback cardinality estimate that is used in case the storage engine cannot provide one (like for ...
Definition: cost_model.h:57
double EstimateRefAccessCost(const TABLE *table, unsigned key_idx, double num_output_rows)
Estimates the cost of an index lookup (ref access).
Definition: cost_model.h:737
double TableAccessIOCost(const TABLE *table, double num_rows, BytesPerTableRow row_size)
Calculate the IO-cost of reading 'num_rows' rows from 'table'.
Definition: cost_model.cc:471
void EstimateSortCost(THD *thd, AccessPath *path, double distinct_rows=kUnknownRowCount)
Estimate costs and output rows for a SORT AccessPath.
Definition: cost_model.cc:658
void EstimateTemptableAggregateCost(THD *thd, AccessPath *path, const Query_block *query_block)
Estimate the costs and row count for a Temp table Aggregate AccessPath.
Definition: cost_model.cc:1723
RangeScanType
Type of range scan operation.
Definition: cost_model.h:680
@ kSingleRange
Plain range scan, without the MRR optimization.
@ kMultiRange
Using the MRR optimization.
BytesPerTableRow EstimateBytesPerRowTable(const TABLE *table)
Estimates the number of bytes that MySQL must process when reading a row from a table,...
Definition: cost_model.h:438
void EstimateWindowCost(AccessPath *path)
Estimate the costs and row count for a WINDOW AccessPath.
Definition: cost_model.cc:1767
bool IsClusteredPrimaryKey(const TABLE *table, unsigned key_idx)
Determines whether a given key on a table is both clustered and primary.
Definition: cost_model.h:317
double CoveringIndexAccessIOCost(const TABLE *table, unsigned key_idx, double num_rows)
Calculate the IO-cost of doing a lookup on index 'key_idx' on 'table' and then read 'num_rows' rows.
Definition: cost_model.cc:526
double EstimateGroupSkipScanCost(TABLE *table, uint key_idx, uint num_groups, bool has_max)
Estimate costs for a group skip scan operation.
Definition: cost_model.cc:1631
double EstimateTableScanCost(const TABLE *table)
Estimates the cost of a full table scan.
Definition: cost_model.h:618
constexpr size_t kMaxItemLengthEstimate
When we make cost estimates, we use this as the maximal length the values we get from evaluating an I...
Definition: cost_model.h:52
void AddCost(THD *thd, const ContainedSubquery &subquery, double num_rows, FilterCost *cost)
Used internally by EstimateFilterCost() only.
Definition: cost_model.cc:715
double EstimateIndexScanCost(const TABLE *table, unsigned key_idx)
Estimates the cost of an index scan.
Definition: cost_model.h:719
void EstimateLimitOffsetCost(AccessPath *path)
Estimate the costs and row count for a WINDOW AccessPath.
Definition: cost_model.cc:1690
double RowReadCostIndex(const TABLE *table, unsigned key_idx, double num_rows)
Computes the cost of reading a number of rows from an index.
Definition: cost_model.h:592
std::span< const Item *const > TermArray
Array of aggregation terms.
Definition: cost_model.h:161
double EstimateSkipScanCost(TABLE *table, uint key_idx, uint num_subrange_scans, ha_rows records)
Estimate costs and result row count for a skip scan operation.
Definition: cost_model.cc:1622
void EstimateDeleteRowsCost(AccessPath *path)
Definition: cost_model.cc:1639
constexpr unsigned kMinEstimatedBytesPerRow
The minimum number of bytes to return for row length estimates.
Definition: cost_model.h:326
int IndexHeight(const TABLE *table, unsigned key_idx)
Estimates the height of a B-tree index.
Definition: cost_model.h:497
double EstimateIndexRangeScanCost(const TABLE *table, unsigned key_idx, RangeScanType scan_type, double num_ranges, double num_output_rows)
Estimates the cost of an index range scan.
Definition: cost_model.cc:571
double FindOutputRowsForJoin(THD *thd, double left_rows, double right_rows, const JoinPredicate *edge)
Estimate the number of output rows from joining two relations.
Definition: cost_model.h:270
void EstimateUpdateRowsCost(AccessPath *path)
Definition: cost_model.cc:1656
constexpr double kBlockFillFactor
This is the estimated fraction of an (innodb) block that is in use (i.e.
Definition: cost_model.h:92
unsigned ClampedBlockSize(const TABLE *table)
We clamp the block size to lie in the interval between the max and min allowed block size for InnoDB ...
Definition: cost_model.h:400
constexpr double kIOStartCost
We model the IO cost for InnoDB tables with the DYNAMIC row format.
Definition: cost_model.h:85
double EstimateDistinctRows(THD *thd, double child_rows, TermArray terms)
Estimate the number of rows with a distinct combination of values for 'terms'.
Definition: cost_model.cc:1560
int64_t CalculateReadSetWidth(const TABLE *table)
Calculate an estimate of the row size of the read set of 'table'.
Definition: cost_model.cc:395
double EstimateIndexBuildCost(double num_rows)
Estimates the one-time cost of building a B-tree index on a materialized temporary table.
Definition: cost_model.h:759
void EstimateMaterializeCost(THD *thd, AccessPath *path)
Provide row estimates and costs for a MATERIALIZE AccessPath.
Definition: cost_model.cc:888
double IndexLookupCost(const TABLE *table, unsigned key_idx)
Estimates the cost of an index lookup.
Definition: cost_model.h:672
void EstimateStreamCost(THD *thd, AccessPath *path)
Estimate the costs and row count for a STREAM AccessPath.
Definition: cost_model.cc:1673
void EstimateAggregateCost(THD *thd, AccessPath *path, const Query_block *query_block)
Estimate costs and result row count for an aggregate operation.
Definition: cost_model.cc:1589
unsigned EstimateBytesPerRowIndex(const TABLE *table, unsigned key_idx)
Estimates the number of bytes that MySQL must process when reading a row from a secondary index,...
Definition: cost_model.h:469
BytesPerTableRow EstimateBytesPerRowWideTable(const TABLE *table)
Estimate the average number of bytes that we need to read from the storage engine when reading a row ...
Definition: cost_model.cc:408
FilterCost EstimateFilterCost(THD *thd, double num_rows, Item *condition, const Query_block *outer_query_block)
Estimate the cost of evaluating “condition”, “num_rows” times.
Definition: cost_model.cc:756
constexpr unsigned kMaxEstimatedBytesPerRow
The maximum number of bytes to return for row length estimates.
Definition: cost_model.h:336
double EstimateSemijoinFanOut(THD *thd, double right_rows, const JoinPredicate &edge)
Estimate the fan out for a left semijoin or a left antijoin.
Definition: cost_model.cc:1777
double RowReadCostTable(const TABLE *table, double num_rows)
Computes the cost of reading a number of rows from a table.
Definition: cost_model.h:573
constexpr double kIOByteCost
The additional cost of reading an extra byte from disk.
Definition: cost_model.h:88
This file includes constants used by all storage engines.
my_off_t ha_rows
Definition: my_base.h:1228
uint bitmap_bits_set(const MY_BITMAP *map)
Definition: my_bitmap.cc:416
static char * path
Definition: mysqldump.cc:151
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
Definition: os0file.h:89
ValueType max(X &&first)
Definition: gtid.h:103
static PSI_metric_info_v1 metrics[]
Definition: plugin.cc:83
T clamp(U x)
Definition: ut0ut.h:412
const mysql_service_registry_t * r
Definition: pfs_example_plugin_employee.cc:86
Access paths are a query planning structure that correspond 1:1 to iterators, in that an access path ...
Definition: access_path.h:243
This struct represents the number of bytes we expect to read for a table row.
Definition: cost_model.h:348
int64_t overflow_bytes
The number of bytes read from overflow pages.
Definition: cost_model.h:360
double overflow_probability
Definition: cost_model.h:367
int64_t record_bytes
The number of bytes read from the B-tree record.
Definition: cost_model.h:353
This class represents a subquery contained in some subclass of Item_subselect,.
Definition: item.h:861
See EstimateFilterCost.
Definition: cost_model.h:95
double init_cost_if_not_materialized
Initial cost before the filter can be applied for the first time.
Definition: cost_model.h:105
double cost_to_materialize
Cost of materializing all subqueries present in the filter.
Definition: cost_model.h:114
double cost_if_materialized
Cost of evaluating the filter for all rows if all subqueries in it have been materialized beforehand.
Definition: cost_model.h:110
double cost_if_not_materialized
Cost of evaluating the filter for all rows if subqueries are not materialized.
Definition: cost_model.h:99
Input to HashJoinCost, for calculating the cost of a hash join.
Definition: cost_model.h:773
double probe_row_size
The average size of rows in the 'probe' input (in bytes).
Definition: cost_model.h:783
double build_rows
The number of rows in the 'build' input.
Definition: cost_model.h:775
double key_size
The size of the join key, in bytes.
Definition: cost_model.h:779
double build_row_size
The average size of rows in the 'build' input (in bytes).
Definition: cost_model.h:777
double probe_rows
The number of rows in the 'probe' input.
Definition: cost_model.h:781
double result_rows
The number of rows in the result set.
Definition: cost_model.h:785
A specification that two specific relational expressions (e.g., two tables, or a table and a join bet...
Definition: access_path.h:80
RelationalExpression * expr
Definition: access_path.h:81
double selectivity
Definition: access_path.h:82
enum RelationalExpression::Type type
@ SEMIJOIN
Left semijoin.
Definition: relational_expression.h:161
@ MULTI_INNER_JOIN
Definition: relational_expression.h:183
@ STRAIGHT_INNER_JOIN
Definition: relational_expression.h:169
@ ANTIJOIN
Left antijoin.
Definition: relational_expression.h:164
@ INNER_JOIN
Definition: relational_expression.h:157
@ FULL_OUTER_JOIN
Definition: relational_expression.h:176
@ TABLE
Definition: relational_expression.h:185
@ LEFT_JOIN
Definition: relational_expression.h:158
Definition: table.h:1456