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

MDEV-6995: EXPLAIN JSON and ORDER BY, GROUP BY, etc

- Make ANALYZE correctly remember and report filesort() calls
- Temp.table use is collected but only basic info is reported.
This commit is contained in:
Sergei Petrunia
2015-06-06 00:32:27 +03:00
parent f7002c05ae
commit 93fc04ff1d
6 changed files with 339 additions and 46 deletions

View File

@ -214,7 +214,7 @@ public:
}
/* Functions to get the statistics */
void print_json(Json_writer *writer);
void print_json_members(Json_writer *writer);
ulonglong get_r_loops() { return r_loops; }
double get_avg_examined_rows()
@ -283,6 +283,7 @@ typedef enum
typedef enum
{
EXPL_ACTION_EOF, /* not-an-action */
EXPL_ACTION_FILESORT,
EXPL_ACTION_TEMPTABLE,
EXPL_ACTION_REMOVE_DUPS,
@ -329,12 +330,121 @@ typedef enum
///TODO: handle repeated execution with subselects!
*/
class Sort_and_group_tracker : public Sql_alloc
{
enum { MAX_QEP_ACTIONS = 5 };
/* Query actions in the order they were made. */
enum_qep_action qep_actions[MAX_QEP_ACTIONS];
/* Number for the next action */
int cur_action;
/*
Non-zero means there was already an execution which had
#total_actions actions
*/
int total_actions;
int get_n_actions()
{
return total_actions? total_actions: cur_action;
}
/*
TRUE<=>there were executions which took different sort/buffer/de-duplicate
routes. The counter values are not meaningful.
*/
bool varied_executions;
/* Details about query actions */
union
{
Filesort_tracker *filesort_tracker;
enum_tmp_table_use tmp_table;
}
qep_actions_data[MAX_QEP_ACTIONS];
Filesort_tracker *dummy_fsort_tracker;
public:
Sort_and_group_tracker() :
cur_action(0), total_actions(0), varied_executions(false),
dummy_fsort_tracker(NULL)
{}
/*************** Reporting interface ***************/
/* Report that join execution is started */
void report_join_start()
{
if (!total_actions && cur_action != 0)
{
/* This is a second execution */
total_actions= cur_action;
}
cur_action= 0;
}
/*
Report that a temporary table is created. The next step is to write to the
this tmp. table
*/
void report_tmp_table(TABLE *tbl);
/*
Report that we are doing a filesort.
@return
Tracker object to be used with filesort
*/
Filesort_tracker *report_sorting();
friend class Iterator;
/*************** Statistics retrieval interface ***************/
bool had_varied_executions() { return varied_executions; }
class Iterator
{
Sort_and_group_tracker *owner;
int idx;
public:
Iterator(Sort_and_group_tracker *owner_arg) :
owner(owner_arg), idx(owner_arg->get_n_actions() - 1)
{}
enum_qep_action get_next(Filesort_tracker **tracker/*,
enum_tmp_table_use *tmp_table_use*/)
{
/* Walk back through the array... */
if (idx < 0)
return EXPL_ACTION_EOF;
switch (owner->qep_actions[idx])
{
case EXPL_ACTION_FILESORT:
*tracker= owner->qep_actions_data[idx].filesort_tracker;
break;
case EXPL_ACTION_TEMPTABLE:
//*tmp_table_use= tmp_table_kind[tmp_table_idx++];
break;
default:
break;
}
return owner->qep_actions[idx--];
}
bool is_last_element() { return idx == -1; }
};
};
#if 0
class Sort_and_group_tracker : public Sql_alloc
{
enum { MAX_QEP_ACTIONS = 5 };
/* Query actions in the order they were made */
enum_qep_action qep_actions[MAX_QEP_ACTIONS];
/* Index in filesort_tracker or tmp_table_kind arrays */
int qep_action_idx[MAX_QEP_ACTIONS];
uint n_actions;
/*
@ -348,7 +458,7 @@ class Sort_and_group_tracker : public Sql_alloc
enum_tmp_table_use tmp_table_kind[2];
int cur_tmp_table;
friend class Explain_select;
//friend class Explain_select;
public:
Sort_and_group_tracker() :
@ -366,7 +476,10 @@ public:
cur_tmp_table= 0;
}
/* Report that a temporary table is created. */
/*
Report that a temporary table is created. The next step is to write to the
this tmp. table
*/
void report_tmp_table(TABLE *tbl)
{
DBUG_ASSERT(n_actions < MAX_QEP_ACTIONS);
@ -385,8 +498,44 @@ public:
DBUG_ASSERT(cur_tracker < 2);
return &filesort_tracker[cur_tracker++];
}
friend class Iterator;
/*************** Statistics retrieval interface ***************/
// need to iterate over steps
#if 0
class Iterator
{
Sort_and_group_tracker *owner;
uint idx;
int fs_tracker_idx;
//int tmp_table_idx;
public:
Iterator(Sort_and_group_tracker *owner_arg) :
owner(owner_arg), idx(0), fs_tracker_idx(0)//, tmp_table_idx(0)
{}
enum_qep_action get_next(Filesort_tracker **tracker/*,
enum_tmp_table_use *tmp_table_use*/)
{
/* Walk back through the array... */
if (idx >= owner->n_actions)
return EXPL_ACTION_EOF;
switch (owner->qep_actions[idx])
{
case EXPL_ACTION_FILESORT:
*tracker= &owner->filesort_tracker[fs_tracker_idx++];
break;
case EXPL_ACTION_TEMPTABLE:
//*tmp_table_use= tmp_table_kind[tmp_table_idx++];
break;
default:
break;
}
return owner->qep_actions[idx++];
}
};
#endif
//enum_tmp_table_use get_tmp_table_type() { return join_result_tmp_table; }
};
#endif