diff options
author | Igor Babaev <igor@askmonty.org> | 2010-12-19 00:44:39 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2010-12-19 00:44:39 -0800 |
commit | 65af63b038cb2ccc0503d6f67f6b70a8e9e438a0 (patch) | |
tree | be759a5029bdf90fe3c979451a954d42f4f6388b /sql/opt_range.h | |
parent | 91f950b1c68089cee799adffdf0abb7ff639b579 (diff) | |
download | mariadb-git-65af63b038cb2ccc0503d6f67f6b70a8e9e438a0.tar.gz |
Addressed the feedback from the review of Monty on the cumulative patch for
mwl#21.
Diffstat (limited to 'sql/opt_range.h')
-rw-r--r-- | sql/opt_range.h | 120 |
1 files changed, 60 insertions, 60 deletions
diff --git a/sql/opt_range.h b/sql/opt_range.h index d894cfaf91d..32a88dd0193 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -328,6 +328,7 @@ public: selects output and/or can produce output suitable for merging. */ virtual void add_info_string(String *str) {} + /* Return 1 if any index used by this quick select uses field which is marked in passed bitmap. @@ -406,9 +407,11 @@ protected: QUICK_RANGE_SELECT *pk_quick_select, READ_RECORD *read_record, bool intersection, + key_map *filtered_scans, Unique **unique_ptr); friend class QUICK_SELECT_DESC; + friend class QUICK_INDEX_SORT_SELECT; friend class QUICK_INDEX_MERGE_SELECT; friend class QUICK_INDEX_INTERSECT_SELECT; friend class QUICK_ROR_INTERSECT_SELECT; @@ -464,40 +467,44 @@ public: /* - QUICK_INDEX_MERGE_SELECT - index_merge access method quick select. + QUICK_INDEX_SORT_SELECT is the base class for the common functionality of: + - QUICK_INDEX_MERGE_SELECT, access based on multi-index merge/union + - QUICK_INDEX_INTERSECT_SELECT, access based on multi-index intersection + - QUICK_INDEX_MERGE_SELECT uses + QUICK_INDEX_SORT_SELECT uses * QUICK_RANGE_SELECTs to get rows - * Unique class to remove duplicate rows + * Unique class + - to remove duplicate rows for QUICK_INDEX_MERGE_SELECT + - to intersect rows for QUICK_INDEX_INTERSECT_SELECT INDEX MERGE OPTIMIZER - Current implementation doesn't detect all cases where index_merge could + 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 + * 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 + 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 imerge_list_or_list and SEL_IMERGE::or_sel_tree_with_checks functions for details. - * There is no "index_merge_ref" method (but index_merge on non-first + * 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 Primary Key (CPK) if the table has one. - The index_merge algorithm consists of two phases: + index merge/intersection uses Unique class for duplicates removal. + index merge/intersection takes advantage of Clustered Primary Key (CPK) + if the table has one. + The index merge/intersection algorithm consists of two phases: + + Phase 1 + (implemented by a QUICK_INDEX_MERGE_SELECT::read_keys_and_merge call): - Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique): prepare() { activate 'index only'; @@ -511,32 +518,31 @@ public: deactivate 'index only'; } - Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next - calls): + Phase 2 + (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next calls): fetch() { - retrieve all rows from row pointers stored in Unique; + retrieve all rows from row pointers stored in Unique + (merging/intersecting them); free Unique; - retrieve all rows for CPK scan; + if (! intersection) + retrieve all rows for CPK scan; } */ -class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I +class QUICK_INDEX_SORT_SELECT : public QUICK_SELECT_I { +protected: Unique *unique; public: - QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table); - ~QUICK_INDEX_MERGE_SELECT(); + QUICK_INDEX_SORT_SELECT(THD *thd, TABLE *table); + ~QUICK_INDEX_SORT_SELECT(); int init(); int reset(void); - int get_next(); bool reverse_sorted() { return false; } bool unique_key_range() { return false; } - int get_type() { return QS_TYPE_INDEX_MERGE; } - void add_keys_and_lengths(String *key_names, String *used_lengths); - void add_info_string(String *str); bool is_keys_used(const MY_BITMAP *fields); #ifndef DBUG_OFF void dbug_dump(int indent, bool verbose); @@ -544,60 +550,54 @@ public: bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range); - /* range quick selects this index_merge read consists of */ + /* range quick selects this index merge/intersect consists of */ List<QUICK_RANGE_SELECT> quick_selects; /* quick select that uses clustered primary key (NULL if none) */ QUICK_RANGE_SELECT* pk_quick_select; - /* true if this select is currently doing a clustered PK scan */ - bool doing_pk_scan; - MEM_ROOT alloc; THD *thd; - int read_keys_and_merge(); + virtual int read_keys_and_merge()= 0; /* used to get rows collected in Unique */ READ_RECORD read_record; }; -class QUICK_INDEX_INTERSECT_SELECT : public QUICK_SELECT_I + + +class QUICK_INDEX_MERGE_SELECT : public QUICK_INDEX_SORT_SELECT { - Unique *unique; +private: + /* true if this select is currently doing a clustered PK scan */ + bool doing_pk_scan; +protected: + int read_keys_and_merge(); + public: - QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table); - ~QUICK_INDEX_INTERSECT_SELECT(); + QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table) + :QUICK_INDEX_SORT_SELECT(thd, table) {} - int init(); - int reset(void); - int get_next(); - bool reverse_sorted() { return false; } - bool unique_key_range() { return false; } - int get_type() { return QS_TYPE_INDEX_INTERSECT; } + int get_next(); + int get_type() { return QS_TYPE_INDEX_MERGE; } void add_keys_and_lengths(String *key_names, String *used_lengths); void add_info_string(String *str); - bool is_keys_used(const MY_BITMAP *fields); -#ifndef DBUG_OFF - void dbug_dump(int indent, bool verbose); -#endif - - bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range); - - /* range quick selects this index_merge read consists of */ - List<QUICK_RANGE_SELECT> quick_selects; - - /* quick select that uses clustered primary key (NULL if none) */ - QUICK_RANGE_SELECT* pk_quick_select; - - /* true if this select is currently doing a clustered PK scan */ - bool doing_pk_scan; +}; - MEM_ROOT alloc; - THD *thd; +class QUICK_INDEX_INTERSECT_SELECT : public QUICK_INDEX_SORT_SELECT +{ +protected: int read_keys_and_merge(); - /* used to get rows collected in Unique */ - READ_RECORD read_record; +public: + QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table) + :QUICK_INDEX_SORT_SELECT(thd, table) {} + + key_map filtered_scans; + int get_next(); + int get_type() { return QS_TYPE_INDEX_INTERSECT; } + void add_keys_and_lengths(String *key_names, String *used_lengths); + void add_info_string(String *str); }; |