summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Stark2010-02-15 02:36:26 +0000
committerGreg Stark2010-02-15 02:36:26 +0000
commit34ebccddcd234df7b4f25d6dd6355a886c831edb (patch)
tree25f3fed8972a269851982696f2ec76a6f3019b58
parentf8c183a1ac02aef14832c1f29946ef2bcb5866b7 (diff)
Display explain buffers measurements in memory units rather than blocks. Also show "Total Buffer Usage" to hint that these are totals not averages per loop
-rw-r--r--src/backend/commands/explain.c98
1 files changed, 74 insertions, 24 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 8c9b060e6b..38ccc84585 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.200 2010/02/01 15:43:35 rhaas Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.201 2010/02/15 02:36:26 stark Exp $
*
*-------------------------------------------------------------------------
*/
@@ -98,6 +98,7 @@ static void ExplainJSONLineEnding(ExplainState *es);
static void ExplainYAMLLineStarting(ExplainState *es);
static void escape_json(StringInfo buf, const char *str);
static void escape_yaml(StringInfo buf, const char *str);
+static double normalize_memory(double amount, char **unit, int *precision);
/*
@@ -1081,47 +1082,63 @@ ExplainNode(Plan *plan, PlanState *planstate,
if (has_shared || has_local || has_temp)
{
appendStringInfoSpaces(es->str, es->indent * 2);
- appendStringInfoString(es->str, "Buffers:");
+ appendStringInfoString(es->str, "Total Buffer Usage:");
if (has_shared)
{
+ char *hit_unit, *read_unit, *written_unit;
+ int hit_prec, read_prec, written_prec;
+ double hit_mem = normalize_memory((double)usage->shared_blks_hit * BLCKSZ, &hit_unit, &hit_prec);
+ double read_mem = normalize_memory((double)usage->shared_blks_read * BLCKSZ, &read_unit, &read_prec);
+ double written_mem = normalize_memory((double)usage->shared_blks_written * BLCKSZ, &written_unit, &written_prec);
+
appendStringInfoString(es->str, " shared");
- if (usage->shared_blks_hit > 0)
- appendStringInfo(es->str, " hit=%ld",
- usage->shared_blks_hit);
+ appendStringInfo(es->str, " hit=%.*f%s",
+ hit_prec, hit_mem, hit_unit);
if (usage->shared_blks_read > 0)
- appendStringInfo(es->str, " read=%ld",
- usage->shared_blks_read);
+ appendStringInfo(es->str, " read=%.*f%s",
+ read_prec, read_mem, read_unit);
if (usage->shared_blks_written > 0)
- appendStringInfo(es->str, " written=%ld",
- usage->shared_blks_written);
+ appendStringInfo(es->str, " written=%.*f%s",
+ written_prec, written_mem, written_unit);
if (has_local || has_temp)
appendStringInfoChar(es->str, ',');
}
if (has_local)
{
- appendStringInfoString(es->str, " local");
- if (usage->local_blks_hit > 0)
- appendStringInfo(es->str, " hit=%ld",
- usage->local_blks_hit);
- if (usage->local_blks_read > 0)
- appendStringInfo(es->str, " read=%ld",
- usage->local_blks_read);
- if (usage->local_blks_written > 0)
- appendStringInfo(es->str, " written=%ld",
- usage->local_blks_written);
+ char *hit_unit, *read_unit, *written_unit;
+ int hit_prec, read_prec, written_prec;
+ double hit_mem = normalize_memory((double)usage->local_blks_hit * BLCKSZ, &hit_unit, &hit_prec);
+ double read_mem = normalize_memory((double)usage->local_blks_read * BLCKSZ, &read_unit, &read_prec);
+ double written_mem = normalize_memory((double)usage->local_blks_written * BLCKSZ, &written_unit, &written_prec);
+
+ appendStringInfoString(es->str, " local");
+ if (usage->local_blks_hit > 0)
+ appendStringInfo(es->str, " hit=%.*f%s",
+ hit_prec, hit_mem, hit_unit);
+ if (usage->local_blks_read > 0)
+ appendStringInfo(es->str, " read=%.*f%s",
+ read_prec, read_mem, read_unit);
+ if (usage->local_blks_written > 0)
+ appendStringInfo(es->str, " written=%.*f%s",
+ written_prec, written_mem, written_unit);
if (has_temp)
appendStringInfoChar(es->str, ',');
}
if (has_temp)
{
+ char *read_unit, *written_unit;
+ int read_prec, written_prec;
+ double read_mem = normalize_memory((double)usage->temp_blks_read * BLCKSZ, &read_unit, &read_prec);
+ double written_mem = normalize_memory((double)usage->temp_blks_written * BLCKSZ, &written_unit, &written_prec);
+
appendStringInfoString(es->str, " temp");
if (usage->temp_blks_read > 0)
- appendStringInfo(es->str, " read=%ld",
- usage->temp_blks_read);
- if (usage->temp_blks_written > 0)
- appendStringInfo(es->str, " written=%ld",
- usage->temp_blks_written);
+ appendStringInfo(es->str, " read=%.*f%s",
+ read_prec, read_mem, read_unit);
+ if (usage->temp_blks_written > 0)
+ appendStringInfo(es->str, " written=%.*f%s",
+ written_prec, written_mem, written_unit);
}
appendStringInfoChar(es->str, '\n');
}
@@ -2153,3 +2170,36 @@ escape_yaml(StringInfo buf, const char *str)
appendStringInfo(buf, "%s", str);
}
+
+/*
+ * For a quantity of bytes pick a reasonable display unit for it and
+ * return the quantity in that unit. Also return the unit name and a
+ * reasonable precision via the reference parameters.
+ */
+
+static double normalize_memory(double amount, char **unit, int *precision)
+{
+ static char *units[] = {"bytes", "kB", "MB", "GB", "TB", "PB"};
+ char **u = units, **last = units + (sizeof(units)/sizeof(*units)-1);
+
+ while (amount > 1024.0 && u < last)
+ {
+ amount /= 1024.0;
+ u += 1;
+ }
+
+ *unit = *u;
+
+ /* if it's bytes or kB then don't print decimals since that's less
+ * than blocksize, otherwise always print 3 significant digits */
+ if (u == units || u == units+1 )
+ *precision = 0;
+ else if (amount < 10)
+ *precision = 2;
+ else if (amount < 100)
+ *precision = 1;
+ else
+ *precision = 0;
+
+ return amount;
+}