MySQL 8.4.0
Source Code Documentation
index_merge.h
Go to the documentation of this file.
1/* Copyright (c) 2000, 2024, 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_RANGE_OPTIMIZER_INDEX_MERGE_H_
25#define SQL_RANGE_OPTIMIZER_INDEX_MERGE_H_
26
27#include <assert.h>
28
29#include "my_alloc.h"
32#include "sql/sql_list.h"
33
34class RowIterator;
35class String;
36class Unique;
37struct MY_BITMAP;
38struct TABLE;
39
40/*
41 IndexMergeIterator - index_merge access method quick select.
42
43 IndexMergeIterator uses
44 * IndexRangeScanIterators to get rows
45 * Unique class to remove duplicate rows
46
47 INDEX MERGE OPTIMIZER
48 Current implementation doesn't detect all cases where index_merge could
49 be used, in particular:
50 * index_merge will never be used if range scan is possible (even if
51 range scan is more expensive)
52
53 * index_merge+'using index' is not supported (this the consequence of
54 the above restriction)
55
56 * If WHERE part contains complex nested AND and OR conditions, some ways
57 to retrieve rows using index_merge will not be considered. The choice
58 of read plan may depend on the order of conjuncts/disjuncts in WHERE
59 part of the query, see comments near imerge_list_or_list and
60 SEL_IMERGE::or_sel_tree_with_checks functions for details.
61
62 * There is no "index_merge_ref" method (but index_merge on non-first
63 table in join is possible with 'range checked for each record').
64
65 See comments around SEL_IMERGE class and test_quick_select for more
66 details.
67
68 ROW RETRIEVAL ALGORITHM
69
70 index_merge uses Unique class for duplicates removal. index_merge takes
71 advantage of Clustered Primary Key (CPK) if the table has one.
72 The index_merge algorithm consists of two phases:
73
74 Phase 1 (implemented in IndexMergeIterator::prepare_unique):
75 prepare()
76 {
77 activate 'index only';
78 while(retrieve next row for non-CPK scan)
79 {
80 if (there is a CPK scan and row will be retrieved by it)
81 skip this row;
82 else
83 put its rowid into Unique;
84 }
85 deactivate 'index only';
86 }
87
88 Phase 2 (implemented as sequence of IndexMergeIterator::Read()
89 calls):
90
91 fetch()
92 {
93 retrieve all rows from row pointers stored in Unique;
94 free Unique;
95 retrieve all rows for CPK scan;
96 }
97*/
98
100 public:
101 // NOTE: Both pk_quick_select (if non-nullptr) and all children must be
102 // of the type IndexRangeScanIterator, possibly wrapped in a TimingIterator.
107 ~IndexMergeIterator() override;
108
109 bool Init() override;
110 int Read() override;
111
112 private:
114
115 /* used to get rows collected in Unique */
117
118 /* quick select that uses clustered primary key (NULL if none) */
120
121 /* range quick selects this index_merge read consists of */
123
124 /* true if this select is currently doing a clustered PK scan */
126
128};
129
130#endif // SQL_RANGE_OPTIMIZER_INDEX_MERGE_H_
Definition: index_merge.h:99
unique_ptr_destroy_only< RowIterator > pk_quick_select
Definition: index_merge.h:119
unique_ptr_destroy_only< RowIterator > read_record
Definition: index_merge.h:116
~IndexMergeIterator() override
Definition: index_merge.cc:65
Mem_root_array< unique_ptr_destroy_only< RowIterator > > m_children
Definition: index_merge.h:122
MEM_ROOT * mem_root
Definition: index_merge.h:127
bool doing_pk_scan
Definition: index_merge.h:125
int Read() override
Read a single row.
Definition: index_merge.cc:220
unique_ptr_destroy_only< Unique > unique
Definition: index_merge.h:113
IndexMergeIterator(THD *thd, MEM_ROOT *mem_root, TABLE *table, unique_ptr_destroy_only< RowIterator > pk_quick_select, Mem_root_array< unique_ptr_destroy_only< RowIterator > > children)
Definition: index_merge.cc:56
bool Init() override
Initialize or reinitialize the iterator.
Definition: index_merge.cc:103
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:426
A context for reading through a single table using a chosen access method: index read,...
Definition: row_iterator.h:82
THD * thd() const
Definition: row_iterator.h:228
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:167
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Definition: row_iterator.h:234
TABLE * table() const
Definition: row_iterator.h:246
Unique – class for unique (removing of duplicates).
Definition: uniques.h:53
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
std::unique_ptr< T, Destroy_only< T > > unique_ptr_destroy_only
std::unique_ptr, but only destroying.
Definition: my_alloc.h:477
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
Definition: my_bitmap.h:43
Definition: table.h:1405