MySQL 8.0.33
Source Code Documentation File Reference
#include "sql/range_optimizer/index_skip_scan_plan.h"
#include <assert.h>
#include <float.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include "m_ctype.h"
#include "my_bitmap.h"
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_table_map.h"
#include "sql/current_thd.h"
#include "sql/field.h"
#include "sql/handler.h"
#include "sql/item.h"
#include "sql/item_sum.h"
#include "sql/join_optimizer/access_path.h"
#include "sql/key.h"
#include "sql/key_spec.h"
#include "sql/opt_costmodel.h"
#include "sql/opt_hints.h"
#include "sql/opt_statistics.h"
#include "sql/opt_trace.h"
#include "sql/opt_trace_context.h"
#include "sql/range_optimizer/index_range_scan_plan.h"
#include "sql/range_optimizer/index_skip_scan.h"
#include "sql/range_optimizer/internal.h"
#include "sql/range_optimizer/path_helpers.h"
#include "sql/range_optimizer/range_opt_param.h"
#include "sql/range_optimizer/tree.h"
#include "sql/sql_bitmap.h"
#include "sql/sql_class.h"
#include "sql/sql_const.h"
#include "sql/sql_lex.h"
#include "sql/sql_optimizer.h"
#include "sql/sql_select.h"
#include "sql/table.h"
#include "sql_string.h"


void trace_basic_info_index_skip_scan (THD *thd, const AccessPath *path, const RANGE_OPT_PARAM *, Opt_trace_object *trace_object)
static void cost_skip_scan (TABLE *table, uint key, uint distinct_key_parts, ha_rows quick_prefix_records, Cost_estimate *cost_est, ha_rows *records, Item *where_cond, Opt_trace_object *trace_idx)
 Compute the cost of a IndexSkipScanIterator for a particular index. More...
AccessPathget_best_skip_scan (THD *thd, RANGE_OPT_PARAM *param, SEL_TREE *tree, enum_order order_direction, bool skip_records_in_range, bool force_skip_scan)
 Test if skip scan is applicable and if so, construct a new AccessPath. More...
void dbug_dump_index_skip_scan (int indent, bool verbose, const AccessPath *path)

Function Documentation

◆ cost_skip_scan()

void cost_skip_scan ( TABLE table,
uint  key,
uint  distinct_key_parts,
ha_rows  quick_prefix_records,
Cost_estimate cost_est,
ha_rows records,
Item where_cond,
Opt_trace_object trace_idx 

Compute the cost of a IndexSkipScanIterator for a particular index.

SYNOPSIS cost_skip_scan() table [in] The table being accessed key [in] The index used to access the table distinct_key_parts [in] Number of key_parts used to get distinct prefix quick_prefix_records [in] Number of records processed by prefix ranges cost_est [out] The cost to retrieve rows via this quick select records [out] The number of rows retrieved where_cond [in] WHERE condition trace_idx [in] optimizer_trace object

DESCRIPTION This method computes the access cost of an INDEX_SKIP_SCAN access path and the number of rows returned.


To estimate the size of the groups to read, index statistics from rec_per_key is used. Each equality range decreases number of the groups to read. The total number of processed records from all the groups will be quick_prefix_records if there are equality ranges else it will be the entire table. Number of distinct group is calculated by dividing the number of processed record by the number keys in a group.

Number of processed records is calculated using following formula:

records = number_of_distinct_groups * records_per_group * filtering_effect

where filtering_effect is filtering effect of the range condition.


◆ dbug_dump_index_skip_scan()

void dbug_dump_index_skip_scan ( int  indent,
bool  verbose,
const AccessPath path 

◆ get_best_skip_scan()

AccessPath * get_best_skip_scan ( THD thd,
SEL_TREE tree,
enum_order  order_direction,
bool  skip_records_in_range,
bool  force_skip_scan 

Test if skip scan is applicable and if so, construct a new AccessPath.

DESCRIPTION Test whether a query can be computed via a IndexSkipScanIterator. The overall query form should look like this:

SELECT A_1,...,A_k, B_1,...,B_m, C FROM T WHERE EQ(A_1,...,A_k) AND RNG(C);

Queries computable via a IndexSkipScanIterator must satisfy the following conditions:

A) Table T has at least one compound index I of the form: I = <A_1,...,A_k, B_1,..., B_m, C ,[D_1,...,D_n]> Keyparts A and D may be empty, but B and C must be non-empty. B) Only one table referenced. C) Cannot have group by/select distinct D) Query must reference fields in the index only. E) The predicates on A_1...A_k must be equality predicates and they need to be constants. This includes the 'IN' operator. F) The query must be a conjunctive query. In other words, it is a AND of ORs: (COND1(kp1) OR COND2(kp1)) AND (COND1(kp2) OR ...) AND ... See get_sel_arg_for_keypart for details. G) There must be a range condition on C. H) Conditions on D columns are allowed. Conditions on D must be in conjunction with range condition on C.

NOTES If the current query satisfies the conditions above, and if (mem_root! = NULL), then the function constructs and returns a new AccessPath object, that is later used to construct a new IndexSkipScanIterator.

paramParameter from test_quick_select
treeRange tree generated by get_mm_tree
order_directionThe sort order the range access method must be able to provide. Three-value logic: asc/desc/don't care
skip_records_in_rangeSame value as JOIN_TAB::skip_records_in_range()
force_skip_scanTRUE if skip scan is forced by optimizer hint
Return values
NULL,ifskip index scan not applicable, otherwise skip index scan table read plan.

◆ trace_basic_info_index_skip_scan()

void trace_basic_info_index_skip_scan ( THD thd,
const AccessPath path,
const RANGE_OPT_PARAM param,
Opt_trace_object trace_object