summaryrefslogtreecommitdiff
path: root/sql/sql_analyze_stmt.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_analyze_stmt.h')
-rw-r--r--sql/sql_analyze_stmt.h153
1 files changed, 105 insertions, 48 deletions
diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h
index abd4fc1ea4b..bf800fd1df6 100644
--- a/sql/sql_analyze_stmt.h
+++ b/sql/sql_analyze_stmt.h
@@ -63,8 +63,8 @@ public:
}
// interface for getting the time
- ulonglong get_loops() { return count; }
- double get_time_ms()
+ ulonglong get_loops() const { return count; }
+ double get_time_ms() const
{
// convert 'cycles' to milliseconds.
return 1000 * ((double)cycles) / sys_timer_info.cycles.frequency;
@@ -169,8 +169,8 @@ class Json_writer;
class Filesort_tracker : public Sql_alloc
{
public:
- Filesort_tracker() :
- r_loops(0), r_limit(0), r_used_pq(0),
+ Filesort_tracker(bool do_timing) :
+ time_tracker(do_timing), r_limit(0), r_used_pq(0),
r_examined_rows(0), r_sorted_rows(0), r_output_rows(0),
sort_passes(0),
sort_buffer_size(0)
@@ -180,10 +180,12 @@ public:
inline void report_use(ha_rows r_limit_arg)
{
- if (!r_loops++)
+ if (!time_tracker.get_loops())
r_limit= r_limit_arg;
else
r_limit= (r_limit != r_limit_arg)? 0: r_limit_arg;
+
+ ANALYZE_START_TRACKING(&time_tracker);
}
inline void incr_pq_used() { r_used_pq++; }
@@ -202,6 +204,7 @@ public:
}
inline void report_merge_passes_at_end(ulong passes)
{
+ ANALYZE_STOP_TRACKING(&time_tracker);
sort_passes += passes;
}
@@ -214,16 +217,16 @@ 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; }
+ ulonglong get_r_loops() const { return time_tracker.get_loops(); }
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()
{
- return ((double)r_output_rows) / r_loops;
+ return ((double)r_output_rows) / get_r_loops();
}
double get_r_filtered()
{
@@ -233,7 +236,9 @@ public:
return 1.0;
}
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".
HA_POS_ERROR means we never had a limit
@@ -283,6 +288,7 @@ typedef enum
typedef enum
{
+ EXPL_ACTION_EOF, /* not-an-action */
EXPL_ACTION_FILESORT,
EXPL_ACTION_TEMPTABLE,
EXPL_ACTION_REMOVE_DUPS,
@@ -333,60 +339,111 @@ class Sort_and_group_tracker : public Sql_alloc
{
enum { MAX_QEP_ACTIONS = 5 };
- /* Query actions in the order they were made */
+ /* Query actions in the order they were made. */
enum_qep_action qep_actions[MAX_QEP_ACTIONS];
- uint n_actions;
- /*
- Trackers for filesort operation. JOIN::exec() may need at most two sorting
- operations.
+ /* Number for the next action */
+ int cur_action;
+
+ /*
+ Non-zero means there was already an execution which had
+ #total_actions actions
*/
- Filesort_tracker filesort_tracker[2];
- int cur_tracker;
-
- /* Information about temporary tables */
- enum_tmp_table_use tmp_table_kind[2];
- int cur_tmp_table;
+ int total_actions;
+
+ int get_n_actions()
+ {
+ return total_actions? total_actions: cur_action;
+ }
- friend class Explain_select;
+ /*
+ 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;
+ bool is_analyze;
public:
- Sort_and_group_tracker() :
- n_actions(0),
- cur_tracker(0),
- cur_tmp_table(0)
+ Sort_and_group_tracker(bool is_analyze_arg) :
+ cur_action(0), total_actions(0), varied_executions(false),
+ dummy_fsort_tracker(NULL),
+ is_analyze(is_analyze_arg)
{}
/*************** Reporting interface ***************/
/* Report that join execution is started */
void report_join_start()
{
- n_actions= 0;
- cur_tracker= 0;
- cur_tmp_table= 0;
+ 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. */
- void report_tmp_table(TABLE *tbl)
- {
- DBUG_ASSERT(n_actions < MAX_QEP_ACTIONS);
- qep_actions[n_actions++]= EXPL_ACTION_TEMPTABLE;
+ /*
+ 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(cur_tmp_table < 2);
- cur_tmp_table++;
- }
+ /*
+ Report that we are doing a filesort.
+ @return
+ Tracker object to be used with filesort
+ */
+ Filesort_tracker *report_sorting(THD *thd);
+
+ /*
+ Report that remove_duplicates() is invoked [on a temp. table].
+ We don't collect any statistics on this operation, yet.
+ */
+ void report_duplicate_removal();
+
+ friend class Iterator;
+ /*************** Statistics retrieval interface ***************/
+ bool had_varied_executions() { return varied_executions; }
- /* Report that we are doing a filesort. */
- Filesort_tracker *report_sorting()
+ class Iterator
{
- DBUG_ASSERT(n_actions < MAX_QEP_ACTIONS);
- qep_actions[n_actions++]= EXPL_ACTION_FILESORT;
-
- DBUG_ASSERT(cur_tracker < 2);
- return &filesort_tracker[cur_tracker++];
- }
-
- /*************** Statistics retrieval interface ***************/
- //enum_tmp_table_use get_tmp_table_type() { return join_result_tmp_table; }
+ 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; }
+ };
};