Commit 69393db3 authored by Sergey Petrunya's avatar Sergey Petrunya

MDEV-3798: EXPLAIN UPDATE/DELETE

- Better EXPLAIN-saving methods for quick selects
parent 8346a498
...@@ -11940,110 +11940,134 @@ void QUICK_SELECT_I::add_key_name(String *str, bool *first) ...@@ -11940,110 +11940,134 @@ void QUICK_SELECT_I::add_key_name(String *str, bool *first)
} }
void QUICK_RANGE_SELECT::save_info(MEM_ROOT *alloc, Explain_quick_select* QUICK_RANGE_SELECT::get_explain(MEM_ROOT *alloc)
Explain_quick_select *explain)
{ {
explain->quick_type= QS_TYPE_RANGE; Explain_quick_select *res;
explain->range.set(alloc, head->key_info[index].name, max_used_key_length); if ((res= new (alloc) Explain_quick_select(QS_TYPE_RANGE)))
res->range.set(alloc, head->key_info[index].name, max_used_key_length);
return res;
} }
void QUICK_GROUP_MIN_MAX_SELECT::save_info(MEM_ROOT *alloc, Explain_quick_select* QUICK_GROUP_MIN_MAX_SELECT::get_explain(MEM_ROOT *alloc)
Explain_quick_select *explain)
{ {
explain->quick_type= QS_TYPE_GROUP_MIN_MAX; Explain_quick_select *res;
explain->range.set(alloc, head->key_info[index].name, max_used_key_length); if ((res= new (alloc) Explain_quick_select(QS_TYPE_GROUP_MIN_MAX)))
res->range.set(alloc, head->key_info[index].name, max_used_key_length);
return res;
} }
void QUICK_INDEX_SORT_SELECT::save_info(MEM_ROOT *alloc, Explain_quick_select* QUICK_INDEX_SORT_SELECT::get_explain(MEM_ROOT *alloc)
Explain_quick_select *explain)
{ {
explain->quick_type= get_type(); Explain_quick_select *res;
if (!(res= new (alloc) Explain_quick_select(get_type())))
return NULL;
QUICK_RANGE_SELECT *quick; QUICK_RANGE_SELECT *quick;
Explain_quick_select *child_qpf; Explain_quick_select *child_explain;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects); List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++)) while ((quick= it++))
{ {
child_qpf= new Explain_quick_select; if ((child_explain= quick->get_explain(alloc)))
explain->children.push_back(child_qpf); res->children.push_back(child_explain);
quick->save_info(alloc, child_qpf); else
return NULL;
} }
if (pk_quick_select) if (pk_quick_select)
{ {
child_qpf= new Explain_quick_select; if ((child_explain= pk_quick_select->get_explain(alloc)))
explain->children.push_back(child_qpf); res->children.push_back(child_explain);
pk_quick_select->save_info(alloc, child_qpf); else
return NULL;
} }
return res;
} }
/* /*
Same as QUICK_INDEX_SORT_SELECT::save_info(), but primary key is printed Same as QUICK_INDEX_SORT_SELECT::get_explain(), but primary key is printed
first first
*/ */
void QUICK_INDEX_INTERSECT_SELECT::save_info(MEM_ROOT *alloc,
Explain_quick_select *explain) Explain_quick_select* QUICK_INDEX_INTERSECT_SELECT::get_explain(MEM_ROOT *alloc)
{ {
explain->quick_type= get_type(); Explain_quick_select *res;
Explain_quick_select *child_qpf; Explain_quick_select *child_explain;
if (!(res= new (alloc) Explain_quick_select(get_type())))
return NULL;
if (pk_quick_select) if (pk_quick_select)
{ {
child_qpf= new Explain_quick_select; if ((child_explain= pk_quick_select->get_explain(alloc)))
explain->children.push_back(child_qpf); res->children.push_back(child_explain);
pk_quick_select->save_info(alloc, child_qpf); else
return NULL;
} }
QUICK_RANGE_SELECT *quick; QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects); List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++)) while ((quick= it++))
{ {
child_qpf= new Explain_quick_select; if ((child_explain= quick->get_explain(alloc)))
explain->children.push_back(child_qpf); res->children.push_back(child_explain);
quick->save_info(alloc, child_qpf); else
return NULL;
} }
return res;
} }
void QUICK_ROR_INTERSECT_SELECT::save_info(MEM_ROOT *alloc, Explain_quick_select* QUICK_ROR_INTERSECT_SELECT::get_explain(MEM_ROOT *alloc)
Explain_quick_select *explain)
{ {
explain->quick_type= get_type(); Explain_quick_select *res;
Explain_quick_select *child_explain;
if (!(res= new (alloc) Explain_quick_select(get_type())))
return NULL;
QUICK_SELECT_WITH_RECORD *qr; QUICK_SELECT_WITH_RECORD *qr;
List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects); List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
while ((qr= it++)) while ((qr= it++))
{ {
Explain_quick_select *child_qpf= new Explain_quick_select; if ((child_explain= qr->quick->get_explain(alloc)))
explain->children.push_back(child_qpf); res->children.push_back(child_explain);
qr->quick->save_info(alloc, child_qpf); else
return NULL;
} }
if (cpk_quick) if (cpk_quick)
{ {
Explain_quick_select *child_qpf= new Explain_quick_select; if ((child_explain= cpk_quick->get_explain(alloc)))
explain->children.push_back(child_qpf); res->children.push_back(child_explain);
cpk_quick->save_info(alloc, child_qpf); else
return NULL;
} }
return res;
} }
void QUICK_ROR_UNION_SELECT::save_info(MEM_ROOT *alloc, Explain_quick_select* QUICK_ROR_UNION_SELECT::get_explain(MEM_ROOT *alloc)
Explain_quick_select *explain)
{ {
explain->quick_type= get_type(); Explain_quick_select *res;
Explain_quick_select *child_explain;
if (!(res= new (alloc) Explain_quick_select(get_type())))
return NULL;
QUICK_SELECT_I *quick; QUICK_SELECT_I *quick;
List_iterator_fast<QUICK_SELECT_I> it(quick_selects); List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
while ((quick= it++)) while ((quick= it++))
{ {
Explain_quick_select *child_qpf= new Explain_quick_select; if ((child_explain= quick->get_explain(alloc)))
explain->children.push_back(child_qpf); res->children.push_back(child_explain);
quick->save_info(alloc, child_qpf); else
return NULL;
} }
return res;
} }
......
...@@ -346,7 +346,7 @@ class QUICK_SELECT_I ...@@ -346,7 +346,7 @@ class QUICK_SELECT_I
void add_key_name(String *str, bool *first); void add_key_name(String *str, bool *first);
/* Save information about quick select's query plan */ /* Save information about quick select's query plan */
virtual void save_info(MEM_ROOT *alloc, Explain_quick_select *explain)= 0; virtual Explain_quick_select* get_explain(MEM_ROOT *alloc)= 0;
/* /*
Return 1 if any index used by this quick select Return 1 if any index used by this quick select
...@@ -473,7 +473,7 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I ...@@ -473,7 +473,7 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
{ file->position(record); } { file->position(record); }
int get_type() { return QS_TYPE_RANGE; } int get_type() { return QS_TYPE_RANGE; }
void add_keys_and_lengths(String *key_names, String *used_lengths); void add_keys_and_lengths(String *key_names, String *used_lengths);
void save_info(MEM_ROOT *alloc, Explain_quick_select *explain); Explain_quick_select *get_explain(MEM_ROOT *alloc);
#ifndef DBUG_OFF #ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose); void dbug_dump(int indent, bool verbose);
#endif #endif
...@@ -610,7 +610,7 @@ class QUICK_INDEX_SORT_SELECT : public QUICK_SELECT_I ...@@ -610,7 +610,7 @@ class QUICK_INDEX_SORT_SELECT : public QUICK_SELECT_I
#ifndef DBUG_OFF #ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose); void dbug_dump(int indent, bool verbose);
#endif #endif
void save_info(MEM_ROOT *alloc, Explain_quick_select *explain); Explain_quick_select *get_explain(MEM_ROOT *alloc);
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range); bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
...@@ -674,7 +674,7 @@ class QUICK_INDEX_INTERSECT_SELECT : public QUICK_INDEX_SORT_SELECT ...@@ -674,7 +674,7 @@ class QUICK_INDEX_INTERSECT_SELECT : public QUICK_INDEX_SORT_SELECT
int get_next(); int get_next();
int get_type() { return QS_TYPE_INDEX_INTERSECT; } int get_type() { return QS_TYPE_INDEX_INTERSECT; }
void add_keys_and_lengths(String *key_names, String *used_lengths); void add_keys_and_lengths(String *key_names, String *used_lengths);
void save_info(MEM_ROOT *alloc, Explain_quick_select *explain); Explain_quick_select *get_explain(MEM_ROOT *alloc);
}; };
...@@ -712,7 +712,7 @@ class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I ...@@ -712,7 +712,7 @@ class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
bool unique_key_range() { return false; } bool unique_key_range() { return false; }
int get_type() { return QS_TYPE_ROR_INTERSECT; } int get_type() { return QS_TYPE_ROR_INTERSECT; }
void add_keys_and_lengths(String *key_names, String *used_lengths); void add_keys_and_lengths(String *key_names, String *used_lengths);
void save_info(MEM_ROOT *alloc, Explain_quick_select *explain); Explain_quick_select *get_explain(MEM_ROOT *alloc);
bool is_keys_used(const MY_BITMAP *fields); bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF #ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose); void dbug_dump(int indent, bool verbose);
...@@ -791,7 +791,7 @@ class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I ...@@ -791,7 +791,7 @@ class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I
bool unique_key_range() { return false; } bool unique_key_range() { return false; }
int get_type() { return QS_TYPE_ROR_UNION; } int get_type() { return QS_TYPE_ROR_UNION; }
void add_keys_and_lengths(String *key_names, String *used_lengths); void add_keys_and_lengths(String *key_names, String *used_lengths);
void save_info(MEM_ROOT *alloc, Explain_quick_select *explain); Explain_quick_select *get_explain(MEM_ROOT *alloc);
bool is_keys_used(const MY_BITMAP *fields); bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF #ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose); void dbug_dump(int indent, bool verbose);
...@@ -940,7 +940,7 @@ class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I ...@@ -940,7 +940,7 @@ class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I
#endif #endif
bool is_agg_distinct() { return have_agg_distinct; } bool is_agg_distinct() { return have_agg_distinct; }
bool loose_scan_is_scanning() { return is_index_scan; } bool loose_scan_is_scanning() { return is_index_scan; }
void save_info(MEM_ROOT *alloc, Explain_quick_select *explain); Explain_quick_select *get_explain(MEM_ROOT *alloc);
}; };
......
...@@ -341,7 +341,10 @@ class Explain_index_use : public Sql_alloc ...@@ -341,7 +341,10 @@ class Explain_index_use : public Sql_alloc
class Explain_quick_select : public Sql_alloc class Explain_quick_select : public Sql_alloc
{ {
public: public:
int quick_type; Explain_quick_select(int quick_type_arg) : quick_type(quick_type_arg)
{}
const int quick_type;
/* This is used when quick_type == QUICK_SELECT_I::QS_TYPE_RANGE */ /* This is used when quick_type == QUICK_SELECT_I::QS_TYPE_RANGE */
Explain_index_use range; Explain_index_use range;
......
...@@ -22657,8 +22657,7 @@ int JOIN::save_explain_data(Explain_query *output, bool need_tmp_table, ...@@ -22657,8 +22657,7 @@ int JOIN::save_explain_data(Explain_query *output, bool need_tmp_table,
*/ */
if (tab->select && tab->select->quick && tab_type != JT_CONST) if (tab->select && tab->select->quick && tab_type != JT_CONST)
{ {
eta->quick_info= new Explain_quick_select; eta->quick_info= tab->select->quick->get_explain(thd->mem_root);
tab->select->quick->save_info(thd->mem_root, eta->quick_info);
} }
if (key_info) /* 'index' or 'ref' access */ if (key_info) /* 'index' or 'ref' access */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment