summaryrefslogtreecommitdiff
path: root/sql/sql_analyze_stmt.h
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2019-11-09 21:03:23 +0300
committerSergei Petrunia <psergey@askmonty.org>2019-11-12 14:40:00 +0300
commit68ed3a81f2113ecdcd5fce0f0cab636d57ff77da (patch)
tree6a1ec5f927a864018475f908c005b314b1feaacf /sql/sql_analyze_stmt.h
parent0117d0e65ac8051bc9f6d14764a2ab05e69bd895 (diff)
downloadmariadb-git-68ed3a81f2113ecdcd5fce0f0cab636d57ff77da.tar.gz
MDEV-20854: ANALYZE for statements: not clear where the time is spent
Count the "gap" time between table accesses and display it as r_other_time_ms in the "table" element. * The advantage of this approach is that it doesn't add any new my_timer_cycles() calls. * The disadvantage is that the definition of what is done during "other time" is not that clear: it includes checking the WHERE (for this table), constructing index lookup tuple (for the next table) writing to GROUP BY temporary table (as we dont account for that time separately [yet], etc)
Diffstat (limited to 'sql/sql_analyze_stmt.h')
-rw-r--r--sql/sql_analyze_stmt.h80
1 files changed, 60 insertions, 20 deletions
diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h
index eec52822ae5..9d5151c3be2 100644
--- a/sql/sql_analyze_stmt.h
+++ b/sql/sql_analyze_stmt.h
@@ -38,6 +38,10 @@ $stmt").
*/
+class Gap_time_tracker;
+void attach_gap_time_tracker(THD *thd, Gap_time_tracker *gap_tracker, ulonglong timeval);
+void process_gap_time_tracker(THD *thd, ulonglong timeval);
+
/*
A class for tracking time it takes to do a certain action
*/
@@ -48,26 +52,37 @@ protected:
ulonglong cycles;
ulonglong last_start;
- void cycles_stop_tracking()
+ void cycles_stop_tracking(THD *thd)
{
ulonglong end= my_timer_cycles();
cycles += end - last_start;
if (unlikely(end < last_start))
cycles += ULONGLONG_MAX;
+
+ process_gap_time_tracker(thd, end);
+ if (my_gap_tracker)
+ attach_gap_time_tracker(thd, my_gap_tracker, end);
}
public:
- Exec_time_tracker() : count(0), cycles(0) {}
-
+ Exec_time_tracker() : count(0), cycles(0), my_gap_tracker(NULL) {}
+
+ /*
+ The time spent between stop_tracking() call on this object and any
+ other time measurement will be billed to this tracker.
+ */
+ Gap_time_tracker *my_gap_tracker;
+
// interface for collecting time
- void start_tracking()
+ void start_tracking(THD *thd)
{
last_start= my_timer_cycles();
+ process_gap_time_tracker(thd, last_start);
}
- void stop_tracking()
+ void stop_tracking(THD *thd)
{
count++;
- cycles_stop_tracking();
+ cycles_stop_tracking(thd);
}
// interface for getting the time
@@ -81,6 +96,31 @@ public:
/*
+ Tracker for time spent between the calls to Exec_time_tracker's {start|
+ stop}_tracking().
+
+ @seealso Gap_time_tracker_data in sql_class.h
+*/
+class Gap_time_tracker
+{
+ ulonglong cycles;
+public:
+ Gap_time_tracker() : cycles(0) {}
+
+ void log_time(ulonglong start, ulonglong end) {
+ cycles += end - start;
+ }
+
+ double get_time_ms() const
+ {
+ // convert 'cycles' to milliseconds.
+ return 1000 * ((double)cycles) / sys_timer_info.cycles.frequency;
+ }
+};
+
+
+
+/*
A class for counting certain actions (in all queries), and optionally
collecting the timings (in ANALYZE queries).
*/
@@ -99,22 +139,22 @@ public:
/*
Unlike Exec_time_tracker::stop_tracking, we don't increase loops.
*/
- void stop_tracking()
+ void stop_tracking(THD *thd)
{
- cycles_stop_tracking();
+ cycles_stop_tracking(thd);
}
};
-#define ANALYZE_START_TRACKING(tracker) \
+#define ANALYZE_START_TRACKING(thd, tracker) \
{ \
(tracker)->incr_loops(); \
if (unlikely((tracker)->timed)) \
- { (tracker)->start_tracking(); } \
+ { (tracker)->start_tracking(thd); } \
}
-#define ANALYZE_STOP_TRACKING(tracker) \
+#define ANALYZE_STOP_TRACKING(thd, tracker) \
if (unlikely((tracker)->timed)) \
- { (tracker)->stop_tracking(); }
+ { (tracker)->stop_tracking(thd); }
/*
A class for collecting read statistics.
@@ -186,14 +226,14 @@ public:
/* Functions that filesort uses to report various things about its execution */
- inline void report_use(ha_rows r_limit_arg)
+ inline void report_use(THD *thd, ha_rows r_limit_arg)
{
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);
+ ANALYZE_START_TRACKING(thd, &time_tracker);
}
inline void incr_pq_used() { r_used_pq++; }
@@ -210,9 +250,9 @@ public:
{
sort_passes -= passes;
}
- inline void report_merge_passes_at_end(ulong passes)
+ inline void report_merge_passes_at_end(THD *thd, ulong passes)
{
- ANALYZE_STOP_TRACKING(&time_tracker);
+ ANALYZE_STOP_TRACKING(thd, &time_tracker);
sort_passes += passes;
}
@@ -318,14 +358,14 @@ public:
container_elements(0), n_checks(0), n_positive_checks(0)
{}
- inline void start_tracking()
+ inline void start_tracking(THD *thd)
{
- ANALYZE_START_TRACKING(&time_tracker);
+ ANALYZE_START_TRACKING(thd, &time_tracker);
}
- inline void stop_tracking()
+ inline void stop_tracking(THD *thd)
{
- ANALYZE_STOP_TRACKING(&time_tracker);
+ ANALYZE_STOP_TRACKING(thd, &time_tracker);
}
/* Save container buffer size in bytes */