MySQL 8.3.0
Source Code Documentation
index_merge.h
Go to the documentation of this file.
1/* Copyright (c) 2000, 2023, 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 also distributed 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 included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef SQL_RANGE_OPTIMIZER_INDEX_MERGE_H_
24#define SQL_RANGE_OPTIMIZER_INDEX_MERGE_H_
25
26#include <assert.h>
27
28#include "my_alloc.h"
31#include "sql/sql_list.h"
32
33class RowIterator;
34class String;
35class Unique;
36struct MY_BITMAP;
37struct TABLE;
38
39/*
40 IndexMergeIterator - index_merge access method quick select.
41
42 IndexMergeIterator uses
43 * IndexRangeScanIterators to get rows
44 * Unique class to remove duplicate rows
45
46 INDEX MERGE OPTIMIZER
47 Current implementation doesn't detect all cases where index_merge could
48 be used, in particular:
49 * index_merge will never be used if range scan is possible (even if
50 range scan is more expensive)
51
52 * index_merge+'using index' is not supported (this the consequence of
53 the above restriction)
54
55 * If WHERE part contains complex nested AND and OR conditions, some ways
56 to retrieve rows using index_merge will not be considered. The choice
57 of read plan may depend on the order of conjuncts/disjuncts in WHERE
58 part of the query, see comments near imerge_list_or_list and
59 SEL_IMERGE::or_sel_tree_with_checks functions for details.
60
61 * There is no "index_merge_ref" method (but index_merge on non-first
62 table in join is possible with 'range checked for each record').
63
64 See comments around SEL_IMERGE class and test_quick_select for more
65 details.
66
67 ROW RETRIEVAL ALGORITHM
68
69 index_merge uses Unique class for duplicates removal. index_merge takes
70 advantage of Clustered Primary Key (CPK) if the table has one.
71 The index_merge algorithm consists of two phases:
72
73 Phase 1 (implemented in IndexMergeIterator::prepare_unique):
74 prepare()
75 {
76 activate 'index only';
77 while(retrieve next row for non-CPK scan)
78 {
79 if (there is a CPK scan and row will be retrieved by it)
80 skip this row;
81 else
82 put its rowid into Unique;
83 }
84 deactivate 'index only';
85 }
86
87 Phase 2 (implemented as sequence of IndexMergeIterator::Read()
88 calls):
89
90 fetch()
91 {
92 retrieve all rows from row pointers stored in Unique;
93 free Unique;
94 retrieve all rows for CPK scan;
95 }
96*/
97
99 public:
100 // NOTE: Both pk_quick_select (if non-nullptr) and all children must be
101 // of the type IndexRangeScanIterator, possibly wrapped in a TimingIterator.
106 ~IndexMergeIterator() override;
107
108 bool Init() override;
109 int Read() override;
110
111 private:
113
114 /* used to get rows collected in Unique */
116
117 /* quick select that uses clustered primary key (NULL if none) */
119
120 /* range quick selects this index_merge read consists of */
122
123 /* true if this select is currently doing a clustered PK scan */
125
127};
128
129#endif // SQL_RANGE_OPTIMIZER_INDEX_MERGE_H_
Definition: index_merge.h:98
unique_ptr_destroy_only< RowIterator > pk_quick_select
Definition: index_merge.h:118
unique_ptr_destroy_only< RowIterator > read_record
Definition: index_merge.h:115
~IndexMergeIterator() override
Definition: index_merge.cc:64
Mem_root_array< unique_ptr_destroy_only< RowIterator > > m_children
Definition: index_merge.h:121
MEM_ROOT * mem_root
Definition: index_merge.h:126
bool doing_pk_scan
Definition: index_merge.h:124
int Read() override
Read a single row.
Definition: index_merge.cc:219
unique_ptr_destroy_only< Unique > unique
Definition: index_merge.h:112
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:55
bool Init() override
Initialize or reinitialize the iterator.
Definition: index_merge.cc:102
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:425
A context for reading through a single table using a chosen access method: index read,...
Definition: row_iterator.h:81
THD * thd() const
Definition: row_iterator.h:227
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:166
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:35
Definition: row_iterator.h:233
TABLE * table() const
Definition: row_iterator.h:245
Unique – class for unique (removing of duplicates).
Definition: uniques.h:52
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:476
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:82
Definition: my_bitmap.h:42
Definition: table.h:1403