mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-3798: EXPLAIN UPDATE/DELETE
- Better EXPLAIN-saving methods for quick selects
This commit is contained in:
114
sql/opt_range.cc
114
sql/opt_range.cc
@ -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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
{ 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 @@ public:
|
|||||||
#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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
#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 @@ public:
|
|||||||
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,
|
|||||||
*/
|
*/
|
||||||
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 */
|
||||||
|
Reference in New Issue
Block a user