MySQL 8.0.39
Source Code Documentation
|
#include <sys/types.h>
#include "my_base.h"
#include "my_inttypes.h"
#include "sql/range_optimizer/range_optimizer.h"
#include "sql/sql_const.h"
Go to the source code of this file.
Classes | |
struct | GroupIndexSkipScanParameters |
Functions | |
AccessPath * | get_best_group_min_max (THD *thd, RANGE_OPT_PARAM *param, SEL_TREE *tree, enum_order order_direction, bool skip_records_in_range, double cost_est) |
Test if this access method is applicable to a GROUP query with MIN/MAX functions, and if so, construct a new AccessPath. More... | |
void | trace_basic_info_group_index_skip_scan (THD *thd, const AccessPath *path, const RANGE_OPT_PARAM *, Opt_trace_object *trace_object) |
void | dbug_dump_group_index_skip_scan (int indent, bool verbose, const AccessPath *path) |
void dbug_dump_group_index_skip_scan | ( | int | indent, |
bool | verbose, | ||
const AccessPath * | path | ||
) |
AccessPath * get_best_group_min_max | ( | THD * | thd, |
RANGE_OPT_PARAM * | param, | ||
SEL_TREE * | tree, | ||
enum_order | order_direction, | ||
bool | skip_records_in_range, | ||
double | cost_est | ||
) |
Test if this access method is applicable to a GROUP query with MIN/MAX functions, and if so, construct a new AccessPath.
DESCRIPTION Test whether a query can be computed via a GroupIndexSkipScanIterator. Queries computable via a GroupIndexSkipScanIterator 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]> B) Query conditions: B0. Q is over a single table T. B1. The attributes referenced by Q are a subset of the attributes of I. B2. All attributes QA in Q can be divided into 3 overlapping groups:
SA1. There is at most one attribute in SA referenced by any number of MIN and/or MAX functions which, which if present, is denoted as C. SA2. The position of the C attribute in the index is after the last A_k. SA3. The attribute C can be referenced in the WHERE clause only in predicates of the forms:
C) Overall query form: SELECT EXPR([A_1,...,A_k], [B_1,...,B_m], [MIN(C)], [MAX(C)]) FROM T WHERE [RNG(A_1,...,A_p ; where p <= k)] [AND EQ(B_1,...,B_m)] [AND PC(C)] [AND PA(A_i1,...,A_iq)] GROUP BY A_1,...,A_k [HAVING PH(A_1, ..., B_1,..., C)] where EXPR(...) is an arbitrary expression over some or all SELECT fields, or: SELECT DISTINCT A_i1,...,A_ik FROM T WHERE [RNG(A_1,...,A_p ; where p <= k)] [AND PA(A_i1,...,A_iq)];
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 GroupIndexSkipScanIterator. If (mem_root == nullptr), then the function only tests whether the current query satisfies the conditions above, and, if so, sets is_applicable = true.
Queries with DISTINCT for which index access can be used are transformed into equivalent group-by queries of the form:
SELECT A_1,...,A_k FROM T WHERE [RNG(A_1,...,A_p ; where p <= k)] [AND PA(A_i1,...,A_iq)] GROUP BY A_1,...,A_k;
The group-by list is a permutation of the select attributes, according to their order in the index.
TODO
thd | Thread handle |
param | Parameter from test_quick_select |
tree | Range tree generated by get_mm_tree |
cost_est | Best cost so far (=table/index scan time) |
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(). |
NULL | Loose index scan not applicable or mem_root == NULL |
!NULL | Loose index scan table read plan |
Test (Part of WA2): Skip loose index scan on disjunctive WHERE clause which results in null tree or merge tree.
The tree structure contains multiple disjoint trees. This happens when the WHERE clause can't be represented in a single range tree due to the disjunctive nature of it but there exists indexes to perform index merge scan.
Skip loose index scan if min_max attribute is present along with at least one other attribute in the WHERE cluse when the tree is null. There is no range tree if WHERE condition can't be represented in a single range tree and index merge is not possible.
Test Part of WA2:If there are conditions on a column C participating in MIN/MAX, those conditions must be conjunctions to all earlier keyparts. Otherwise, Loose Index Scan cannot be used.
void trace_basic_info_group_index_skip_scan | ( | THD * | thd, |
const AccessPath * | path, | ||
const RANGE_OPT_PARAM * | , | ||
Opt_trace_object * | trace_object | ||
) |