MySQL 9.5.0
Source Code Documentation
index_skip_scan_plan.cc 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 <memory>
#include "my_bitmap.h"
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_table_map.h"
#include "mysql/strings/m_ctype.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/join_optimizer/cost_model.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"

Functions

void trace_basic_info_index_skip_scan (THD *thd, const AccessPath *path, const RANGE_OPT_PARAM *, Opt_trace_object *trace_object)
 
static bool find_skip_scans (THD *thd, RANGE_OPT_PARAM *param, SEL_TREE *tree, enum_order order_direction, bool skip_records_in_range, bool find_all_skip_scans, Mem_root_array< IndexSkipScanParameters * > *skip_scan_info_list)
 Collect all possible index skip scans and store them in the skip_scan_info_list. More...
 
static AccessPathmake_skip_scan_path (RANGE_OPT_PARAM *param, bool force_skip_scan, IndexSkipScanParameters *skip_scan_info)
 Construct a new INDEX_SKIP_SCAN AccessPath from the IndexSkipScanParameters. More...
 
Mem_root_array< AccessPath * > get_all_skip_scans (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 for each candidate index skip scan. 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...
 
static bool setup_range_for_skip_scan (SEL_ARG *range_sel_arg, RANGE_OPT_PARAM *param, IndexSkipScanParameters *skip_scan_info)
 Set up ranges for index skip scan. More...
 
void dbug_dump_index_skip_scan (int indent, bool verbose, const AccessPath *path)
 

Function Documentation

◆ dbug_dump_index_skip_scan()

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

◆ find_skip_scans()

bool find_skip_scans ( THD thd,
RANGE_OPT_PARAM param,
SEL_TREE tree,
enum_order  order_direction,
bool  skip_records_in_range,
bool  find_all_skip_scans,
Mem_root_array< IndexSkipScanParameters * > *  skip_scan_info_list 
)
static

Collect all possible index skip scans and store them in the skip_scan_info_list.

Parameters
thdThread info
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()
find_all_skip_scansTRUE if every possible skip scan should be added to skip scan list, FALSE if the best skip scan should be added
[out]skip_scan_info_listList of index skip scans
Return values
trueon error, otherwise false.

◆ get_all_skip_scans()

Mem_root_array< AccessPath * > get_all_skip_scans ( 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 for each candidate index skip scan.

Parameters
thdThread info
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
Mem_root_arrayof candidate INDEX_SKIP_SCAN AccessPaths.

◆ get_best_skip_scan()

AccessPath * get_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.

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.

Parameters
thdThread info
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 index skip scan access path.

◆ make_skip_scan_path()

AccessPath * make_skip_scan_path ( RANGE_OPT_PARAM param,
bool  force_skip_scan,
IndexSkipScanParameters skip_scan_info 
)
static

Construct a new INDEX_SKIP_SCAN AccessPath from the IndexSkipScanParameters.

Parameters
paramParameter from test_quick_select
force_skip_scanTRUE if skip scan is forced by optimizer hint
skip_scan_infoParameters of index skip scan
Return values
INDEX_SKIP_SCANAccessPath

◆ setup_range_for_skip_scan()

static bool setup_range_for_skip_scan ( SEL_ARG range_sel_arg,
RANGE_OPT_PARAM param,
IndexSkipScanParameters skip_scan_info 
)
static

Set up ranges for index skip scan.

  • Set flags in skip scan info for null conditions and equality ranges based on the range condition
  • Alloc storage and set values of min/max range keys
Parameters
range_sel_argRange condition info
paramParameter from test_quick_select
skip_scan_infoInfo about a single index skip scan
Return values
trueon error, otherwise false

◆ 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 
)