summaryrefslogtreecommitdiff
path: root/sql/opt_range.h
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2003-12-09 23:40:02 +0300
committerunknown <sergefp@mysql.com>2003-12-09 23:40:02 +0300
commite7526d3a209160a5fb6ba02208dcfac515c858b2 (patch)
tree993bf61744309dc8fb141dc11bc16af4c0a8f26f /sql/opt_range.h
parentd8010263a5abc731affd3482f117ef219af75d06 (diff)
downloadmariadb-git-e7526d3a209160a5fb6ba02208dcfac515c858b2.tar.gz
Two-sweeps read index_merge plus several small index_merge fixes and improvements
Diffstat (limited to 'sql/opt_range.h')
-rw-r--r--sql/opt_range.h85
1 files changed, 77 insertions, 8 deletions
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 9e392104818..35a0cb5df88 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -68,7 +68,7 @@ class QUICK_RANGE :public Sql_alloc {
/*
Quick select interface.
- This class is parent for all QUICK_*_SELECT and FT_SELECT classes.
+ This class is a parent for all QUICK_*_SELECT and FT_SELECT classes.
*/
class QUICK_SELECT_I
@@ -128,19 +128,29 @@ protected:
SEL_ARG *key_tree,
MEM_ROOT *alloc);
friend class QUICK_SELECT_DESC;
+ friend class QUICK_INDEX_MERGE_SELECT;
+
+ DYNAMIC_ARRAY ranges; /* ordered array of range ptrs */
+ QUICK_RANGE **cur_range; /* current element in ranges */
- List<QUICK_RANGE> ranges;
- List_iterator<QUICK_RANGE> it;
QUICK_RANGE *range;
MEM_ROOT alloc;
KEY_PART *key_parts;
int cmp_next(QUICK_RANGE *range);
+ int cmp_prev(QUICK_RANGE *range);
+ bool row_in_ranges();
public:
QUICK_RANGE_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0,
MEM_ROOT *parent_alloc=NULL);
~QUICK_RANGE_SELECT();
- int reset(void) { next=0; it.rewind(); return 0; }
+ int reset(void)
+ {
+ next=0;
+ range= NULL;
+ cur_range= NULL;
+ return 0;
+ }
int init();
int get_next();
bool reverse_sorted() { return 0; }
@@ -148,9 +158,60 @@ public:
int get_type() { return QS_TYPE_RANGE; }
};
+
/*
- Index merge quick select.
- It is implemented as a container for several QUICK_RANGE_SELECTs.
+QUICK_INDEX_MERGE_SELECT - index_merge acces method quick select.
+
+ QUICK_INDEX_MERGE_SELECT uses
+ * QUICK_RANGE_SELECTs to get rows
+ * Unique class to remove duplicate rows
+
+INDEX MERGE OPTIMIZER
+ Current implementation doesn't detect all cases where index_merge could be
+ used, in particular:
+ * index_merge will never be used if range scan is possible (even if range
+ scan is more expensive)
+
+ * index_merge+'using index' is not supported (this the consequence of the
+ above restriction)
+
+ * If WHERE part contains complex nested AND and OR conditions, some ways to
+ retrieve rows using index_merge will not be considered. The choice of
+ read plan may depend on the order of conjuncts/disjuncts in WHERE part of
+ the query, see comments near SEL_IMERGE::or_sel_tree_with_checks and
+ imerge_list_or_list function for details.
+
+ * there is no "index_merge_ref" method (but index_merge on non-first table
+ in join is possible with 'range checked for each record').
+
+ See comments around SEL_IMERGE class and test_quick_select for more details.
+
+ROW RETRIEVAL ALGORITHM
+
+ index_merge uses Unique class for duplicates removal. Index merge takes
+ advantage of clustered covering primary key (CCPK) if the table has one.
+ The algorithm is as follows:
+
+ prepare() //implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique
+ {
+ activate 'index only';
+ while(retrieve next row for non-CCPK scan)
+ {
+ if (there is a CCPK scan and row will be retrieved by it)
+ skip this row;
+ else
+ put rowid into Unique;
+ }
+ deactivate 'index only';
+ }
+
+ fetch() //implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next calls
+ {
+ retrieve all rows from row pointers stored in Unique;
+ free Unique;
+ retrieve all rows for CCPK scan;
+ }
+
*/
class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
@@ -175,8 +236,14 @@ public:
List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it;
QUICK_RANGE_SELECT* cur_quick_select;
- /* last element in quick_selects list. */
+ /* last element in quick_selects list */
QUICK_RANGE_SELECT* last_quick_select;
+
+ /* quick select that uses Covering Clustered Primary Key (NULL if none) */
+ QUICK_RANGE_SELECT* pk_quick_select;
+
+ /* true if this select is currently doing a CCPK scan */
+ bool doing_pk_scan;
Unique *unique;
MEM_ROOT alloc;
@@ -184,6 +251,9 @@ public:
THD *thd;
int prepare_unique();
bool reset_called;
+
+ /* used to get rows collected in Unique */
+ READ_RECORD read_record;
};
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
@@ -194,7 +264,6 @@ public:
bool reverse_sorted() { return 1; }
int get_type() { return QS_TYPE_RANGE_DESC; }
private:
- int cmp_prev(QUICK_RANGE *range);
bool range_reads_after_key(QUICK_RANGE *range);
#ifdef NOT_USED
bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);