1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Addressed the feedback from the review of Monty on the cumulative patch for

mwl#21.
This commit is contained in:
Igor Babaev
2010-12-19 00:44:39 -08:00
parent 91f950b1c6
commit 65af63b038
6 changed files with 532 additions and 417 deletions

View File

@ -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
{
Unique *unique;
public:
QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table);
~QUICK_INDEX_INTERSECT_SELECT();
int init();
int reset(void);
int get_next();
bool reverse_sorted() { return false; }
bool unique_key_range() { return false; }
class QUICK_INDEX_MERGE_SELECT : public QUICK_INDEX_SORT_SELECT
{
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_MERGE_SELECT(THD *thd, TABLE *table)
:QUICK_INDEX_SORT_SELECT(thd, table) {}
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);
};
class QUICK_INDEX_INTERSECT_SELECT : public QUICK_INDEX_SORT_SELECT
{
protected:
int read_keys_and_merge();
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);
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;
int read_keys_and_merge();
/* used to get rows collected in Unique */
READ_RECORD read_record;
};