MySQL 8.0.39
Source Code Documentation
|
#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"
Functions | |
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... | |
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. More... | |
void | dbug_dump_index_skip_scan (int indent, bool verbose, const AccessPath *path) |
|
static |
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.
NOTES
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.
RETURN None
void dbug_dump_index_skip_scan | ( | int | indent, |
bool | verbose, | ||
const AccessPath * | path | ||
) |
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.
param | Parameter from test_quick_select |
tree | Range tree generated by get_mm_tree |
order_direction | The sort order the range access method must be able to provide. Three-value logic: asc/desc/don't care |
skip_records_in_range | Same value as JOIN_TAB::skip_records_in_range() |
force_skip_scan | TRUE if skip scan is forced by optimizer hint |
NULL,if | skip index scan not applicable, otherwise skip index scan table read plan. |
void trace_basic_info_index_skip_scan | ( | THD * | thd, |
const AccessPath * | path, | ||
const RANGE_OPT_PARAM * | param, | ||
Opt_trace_object * | trace_object | ||
) |