1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Make ANALYZE FORMAT=JSON show execution time for filesort element.

This commit is contained in:
Sergei Petrunia
2015-08-07 17:41:35 +03:00
parent afd59b575a
commit 3025c42605
7 changed files with 48 additions and 23 deletions

View File

@@ -40,6 +40,7 @@ ANALYZE
"r_total_time_ms": "REPLACED", "r_total_time_ms": "REPLACED",
"filesort": { "filesort": {
"r_loops": 1, "r_loops": 1,
"r_total_time_ms": "REPLACED",
"r_limit": 5, "r_limit": 5,
"r_used_priority_queue": true, "r_used_priority_queue": true,
"r_output_rows": 6, "r_output_rows": 6,
@@ -140,6 +141,7 @@ ANALYZE
"r_total_time_ms": "REPLACED", "r_total_time_ms": "REPLACED",
"filesort": { "filesort": {
"r_loops": 1, "r_loops": 1,
"r_total_time_ms": "REPLACED",
"r_used_priority_queue": false, "r_used_priority_queue": false,
"r_output_rows": 10000, "r_output_rows": 10000,
"r_buffer_size": "REPLACED", "r_buffer_size": "REPLACED",
@@ -204,6 +206,7 @@ ANALYZE
"r_total_time_ms": "REPLACED", "r_total_time_ms": "REPLACED",
"filesort": { "filesort": {
"r_loops": 1, "r_loops": 1,
"r_total_time_ms": "REPLACED",
"r_limit": 4, "r_limit": 4,
"r_used_priority_queue": true, "r_used_priority_queue": true,
"r_output_rows": 4, "r_output_rows": 4,
@@ -288,6 +291,7 @@ ANALYZE
"r_rows": 10, "r_rows": 10,
"filesort": { "filesort": {
"r_loops": 1, "r_loops": 1,
"r_total_time_ms": "REPLACED",
"r_used_priority_queue": false, "r_used_priority_queue": false,
"r_output_rows": 10, "r_output_rows": 10,
"r_buffer_size": "REPLACED", "r_buffer_size": "REPLACED",
@@ -343,6 +347,7 @@ ANALYZE
"r_total_time_ms": "REPLACED", "r_total_time_ms": "REPLACED",
"filesort": { "filesort": {
"r_loops": 1, "r_loops": 1,
"r_total_time_ms": "REPLACED",
"r_used_priority_queue": false, "r_used_priority_queue": false,
"r_output_rows": 10, "r_output_rows": 10,
"r_buffer_size": "REPLACED", "r_buffer_size": "REPLACED",
@@ -451,11 +456,13 @@ ANALYZE
"r_total_time_ms": "REPLACED", "r_total_time_ms": "REPLACED",
"filesort": { "filesort": {
"r_loops": 1, "r_loops": 1,
"r_total_time_ms": "REPLACED",
"r_limit": 1, "r_limit": 1,
"r_used_priority_queue": true, "r_used_priority_queue": true,
"r_output_rows": 2, "r_output_rows": 2,
"filesort": { "filesort": {
"r_loops": 1, "r_loops": 1,
"r_total_time_ms": "REPLACED",
"r_used_priority_queue": false, "r_used_priority_queue": false,
"r_output_rows": 6, "r_output_rows": 6,
"r_buffer_size": "REPLACED", "r_buffer_size": "REPLACED",

View File

@@ -371,7 +371,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
err: err:
my_free(param.tmp_buffer); my_free(param.tmp_buffer);
tracker->report_merge_passes_at_end(thd->query_plan_fsort_passes);
if (!subselect || !subselect->is_uncacheable()) if (!subselect || !subselect->is_uncacheable())
{ {
table_sort.free_sort_buffer(); table_sort.free_sort_buffer();
@@ -393,6 +392,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
outfile->end_of_file=save_pos; outfile->end_of_file=save_pos;
} }
} }
tracker->report_merge_passes_at_end(thd->query_plan_fsort_passes);
if (error) if (error)
{ {
int kill_errno= thd->killed_errno(); int kill_errno= thd->killed_errno();

View File

@@ -26,29 +26,38 @@
void Filesort_tracker::print_json_members(Json_writer *writer) void Filesort_tracker::print_json_members(Json_writer *writer)
{ {
const char *varied_str= "(varied across executions)"; const char *varied_str= "(varied across executions)";
writer->add_member("r_loops").add_ll(r_loops); writer->add_member("r_loops").add_ll(get_r_loops());
if (get_r_loops() && time_tracker.timed)
{
writer->add_member("r_total_time_ms").
add_double(time_tracker.get_time_ms());
}
if (r_limit != HA_POS_ERROR) if (r_limit != HA_POS_ERROR)
{ {
writer->add_member("r_limit"); writer->add_member("r_limit");
if (r_limit == 0) if (r_limit == 0)
writer->add_str(varied_str); writer->add_str(varied_str);
else else
writer->add_ll(rint(r_limit/r_loops)); writer->add_ll(rint(r_limit/get_r_loops()));
} }
writer->add_member("r_used_priority_queue"); writer->add_member("r_used_priority_queue");
if (r_used_pq == r_loops) if (r_used_pq == get_r_loops())
writer->add_bool(true); writer->add_bool(true);
else if (r_used_pq == 0) else if (r_used_pq == 0)
writer->add_bool(false); writer->add_bool(false);
else else
writer->add_str(varied_str); writer->add_str(varied_str);
writer->add_member("r_output_rows").add_ll(rint(r_output_rows / r_loops)); writer->add_member("r_output_rows").add_ll(rint(r_output_rows /
get_r_loops()));
if (sort_passes) if (sort_passes)
writer->add_member("r_sort_passes").add_ll(rint(sort_passes / r_loops)); {
writer->add_member("r_sort_passes").add_ll(rint(sort_passes /
get_r_loops()));
}
if (sort_buffer_size != 0) if (sort_buffer_size != 0)
{ {
@@ -79,13 +88,13 @@ Filesort_tracker *Sort_and_group_tracker::report_sorting(THD *thd)
varied_executions= true; varied_executions= true;
cur_action++; cur_action++;
if (!dummy_fsort_tracker) if (!dummy_fsort_tracker)
dummy_fsort_tracker= new (thd->mem_root) Filesort_tracker(); dummy_fsort_tracker= new (thd->mem_root) Filesort_tracker(is_analyze);
return dummy_fsort_tracker; return dummy_fsort_tracker;
} }
return qep_actions_data[cur_action++].filesort_tracker; return qep_actions_data[cur_action++].filesort_tracker;
} }
Filesort_tracker *fs_tracker= new(thd->mem_root)Filesort_tracker(); Filesort_tracker *fs_tracker= new(thd->mem_root)Filesort_tracker(is_analyze);
qep_actions_data[cur_action].filesort_tracker= fs_tracker; qep_actions_data[cur_action].filesort_tracker= fs_tracker;
qep_actions[cur_action++]= EXPL_ACTION_FILESORT; qep_actions[cur_action++]= EXPL_ACTION_FILESORT;

View File

@@ -63,8 +63,8 @@ public:
} }
// interface for getting the time // interface for getting the time
ulonglong get_loops() { return count; } ulonglong get_loops() const { return count; }
double get_time_ms() double get_time_ms() const
{ {
// convert 'cycles' to milliseconds. // convert 'cycles' to milliseconds.
return 1000 * ((double)cycles) / sys_timer_info.cycles.frequency; return 1000 * ((double)cycles) / sys_timer_info.cycles.frequency;
@@ -169,8 +169,8 @@ class Json_writer;
class Filesort_tracker : public Sql_alloc class Filesort_tracker : public Sql_alloc
{ {
public: public:
Filesort_tracker() : Filesort_tracker(bool do_timing) :
r_loops(0), r_limit(0), r_used_pq(0), time_tracker(do_timing), r_limit(0), r_used_pq(0),
r_examined_rows(0), r_sorted_rows(0), r_output_rows(0), r_examined_rows(0), r_sorted_rows(0), r_output_rows(0),
sort_passes(0), sort_passes(0),
sort_buffer_size(0) sort_buffer_size(0)
@@ -180,10 +180,12 @@ public:
inline void report_use(ha_rows r_limit_arg) inline void report_use(ha_rows r_limit_arg)
{ {
if (!r_loops++) if (!time_tracker.get_loops())
r_limit= r_limit_arg; r_limit= r_limit_arg;
else else
r_limit= (r_limit != r_limit_arg)? 0: r_limit_arg; r_limit= (r_limit != r_limit_arg)? 0: r_limit_arg;
ANALYZE_START_TRACKING(&time_tracker);
} }
inline void incr_pq_used() { r_used_pq++; } inline void incr_pq_used() { r_used_pq++; }
@@ -202,6 +204,7 @@ public:
} }
inline void report_merge_passes_at_end(ulong passes) inline void report_merge_passes_at_end(ulong passes)
{ {
ANALYZE_STOP_TRACKING(&time_tracker);
sort_passes += passes; sort_passes += passes;
} }
@@ -216,14 +219,14 @@ public:
/* Functions to get the statistics */ /* Functions to get the statistics */
void print_json_members(Json_writer *writer); void print_json_members(Json_writer *writer);
ulonglong get_r_loops() { return r_loops; } ulonglong get_r_loops() const { return time_tracker.get_loops(); }
double get_avg_examined_rows() double get_avg_examined_rows()
{ {
return ((double)r_examined_rows) / r_loops; return ((double)r_examined_rows) / get_r_loops();
} }
double get_avg_returned_rows() double get_avg_returned_rows()
{ {
return ((double)r_output_rows) / r_loops; return ((double)r_output_rows) / get_r_loops();
} }
double get_r_filtered() double get_r_filtered()
{ {
@@ -233,7 +236,9 @@ public:
return 1.0; return 1.0;
} }
private: private:
ulonglong r_loops; /* How many times filesort was invoked */ Time_and_counter_tracker time_tracker;
//ulonglong r_loops; /* How many times filesort was invoked */
/* /*
LIMIT is typically a constant. There is never "LIMIT 0". LIMIT is typically a constant. There is never "LIMIT 0".
HA_POS_ERROR means we never had a limit HA_POS_ERROR means we never had a limit
@@ -366,11 +371,12 @@ class Sort_and_group_tracker : public Sql_alloc
qep_actions_data[MAX_QEP_ACTIONS]; qep_actions_data[MAX_QEP_ACTIONS];
Filesort_tracker *dummy_fsort_tracker; Filesort_tracker *dummy_fsort_tracker;
bool is_analyze;
public: public:
Sort_and_group_tracker() : Sort_and_group_tracker(bool is_analyze_arg) :
cur_action(0), total_actions(0), varied_executions(false), cur_action(0), total_actions(0), varied_executions(false),
dummy_fsort_tracker(NULL) dummy_fsort_tracker(NULL),
is_analyze(is_analyze_arg)
{} {}
/*************** Reporting interface ***************/ /*************** Reporting interface ***************/

View File

@@ -159,7 +159,7 @@ void Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
explain->where_cond= select? select->cond: NULL; explain->where_cond= select? select->cond: NULL;
if (using_filesort) if (using_filesort)
explain->filesort_tracker= new (mem_root) Filesort_tracker; explain->filesort_tracker= new (mem_root) Filesort_tracker(is_analyze);
explain->using_io_buffer= using_io_buffer; explain->using_io_buffer= using_io_buffer;
append_possible_keys(mem_root, explain->possible_keys, table, append_possible_keys(mem_root, explain->possible_keys, table,

View File

@@ -210,7 +210,8 @@ public:
Explain_basic_join(root), Explain_basic_join(root),
message(NULL), message(NULL),
using_temporary(false), using_filesort(false), using_temporary(false), using_filesort(false),
time_tracker(is_analyze) time_tracker(is_analyze),
ops_tracker(is_analyze)
{} {}
/* /*
@@ -729,6 +730,8 @@ private:
This is similar to Explain_table_access, except that it is more restrictive. This is similar to Explain_table_access, except that it is more restrictive.
Also, it can have UPDATE operation options, but currently there aren't any. Also, it can have UPDATE operation options, but currently there aren't any.
Explain_delete inherits from this.
*/ */
class Explain_update : public Explain_node class Explain_update : public Explain_node

View File

@@ -9374,7 +9374,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
tables.db= from->s->db.str; tables.db= from->s->db.str;
THD_STAGE_INFO(thd, stage_sorting); THD_STAGE_INFO(thd, stage_sorting);
Filesort_tracker dummy_tracker; Filesort_tracker dummy_tracker(false);
if (thd->lex->select_lex.setup_ref_array(thd, order_num) || if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array, setup_order(thd, thd->lex->select_lex.ref_pointer_array,
&tables, fields, all_fields, order) || &tables, fields, all_fields, order) ||