1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLED_OPTIMIZER_QUICK_INDEX_MERGE_SELECT_H
21
#define DRIZZLED_OPTIMIZER_QUICK_INDEX_MERGE_SELECT_H
23
#include "drizzled/optimizer/range.h"
32
@class QuickIndexMergeSelect - index_merge access method quick select.
34
QuickIndexMergeSelect uses
35
* QuickRangeSelects to get rows
36
* Unique class to remove duplicate rows
39
Current implementation doesn't detect all cases where index_merge could
40
be used, in particular:
41
* index_merge will never be used if range scan is possible (even if
42
range scan is more expensive)
44
* index_merge+'using index' is not supported (this the consequence of
45
the above restriction)
47
* If WHERE part contains complex nested AND and OR conditions, some ways
48
to retrieve rows using index_merge will not be considered. The choice
49
of read plan may depend on the order of conjuncts/disjuncts in WHERE
50
part of the query, see comments near imerge_list_or_list and
51
SEL_IMERGE::or_sel_tree_with_checks functions for details.
53
* There is no "index_merge_ref" method (but index_merge on non-first
54
table in join is possible with 'range checked for each record').
56
See comments around SEL_IMERGE class and test_quick_select for more
59
ROW RETRIEVAL ALGORITHM
61
index_merge uses Unique class for duplicates removal. index_merge takes
62
advantage of Clustered Primary Key (CPK) if the table has one.
63
The index_merge algorithm consists of two phases:
65
Phase 1 (implemented in QuickIndexMergeSelect::prepare_unique):
68
activate 'index only';
69
while(retrieve next row for non-CPK scan)
71
if (there is a CPK scan and row will be retrieved by it)
74
put its rowid into Unique;
76
deactivate 'index only';
79
Phase 2 (implemented as sequence of QuickIndexMergeSelect::get_next
84
retrieve all rows from row pointers stored in Unique;
86
retrieve all rows for CPK scan;
89
class QuickIndexMergeSelect : public QuickSelectInterface
93
QuickIndexMergeSelect(Session *session, Table *table);
95
~QuickIndexMergeSelect();
101
* Get next row for index_merge.
103
* The rows are read from
104
* 1. rowids stored in Unique.
105
* 2. QuickRangeSelect with clustered primary key (if any).
106
* The sets of rows retrieved in 1) and 2) are guaranteed to be disjoint.
110
bool reverse_sorted()
115
bool unique_key_range()
122
return QS_TYPE_INDEX_MERGE;
125
void add_keys_and_lengths(String *key_names, String *used_lengths);
126
void add_info_string(String *str);
127
bool is_keys_used(const MyBitmap *fields);
129
bool push_quick_back(QuickRangeSelect *quick_sel_range);
131
/* range quick selects this index_merge read consists of */
132
List<QuickRangeSelect> quick_selects;
134
/* quick select that uses clustered primary key (NULL if none) */
135
QuickRangeSelect* pk_quick_select;
137
/* true if this select is currently doing a clustered PK scan */
144
* Perform key scans for all used indexes (except CPK), get rowids and merge
145
* them into an ordered non-recurrent sequence of rowids.
147
* The merge/duplicate removal is performed using Unique class. We put all
148
* rowids into Unique, get the sorted sequence and destroy the Unique.
150
* If table has a clustered primary key that covers all rows (true for bdb
151
* and innodb currently) and one of the index_merge scans is a scan on PK,
152
* then rows that will be retrieved by PK scan are not put into Unique and
153
* primary key scan is not performed here, it is performed later separately.
157
* @retval other error
159
int read_keys_and_merge();
161
/* used to get rows collected in Unique */
162
READ_RECORD read_record;
165
} /* namespace optimizer */
167
} /* namespace drizzled */
169
#endif /* DRIZZLED_OPTIMIZER_QUICK_INDEX_MERGE_SELECT_H */