Commit 34ebccdd authored by Greg Stark's avatar Greg Stark

Display explain buffers measurements in memory units rather than blocks. Also...

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
parent f8c183a1
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California * Portions Copyright (c) 1994-5, Regents of the University of California
* *
* IDENTIFICATION * 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); ...@@ -98,6 +98,7 @@ static void ExplainJSONLineEnding(ExplainState *es);
static void ExplainYAMLLineStarting(ExplainState *es); static void ExplainYAMLLineStarting(ExplainState *es);
static void escape_json(StringInfo buf, const char *str); static void escape_json(StringInfo buf, const char *str);
static void escape_yaml(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, ...@@ -1081,47 +1082,63 @@ ExplainNode(Plan *plan, PlanState *planstate,
if (has_shared || has_local || has_temp) if (has_shared || has_local || has_temp)
{ {
appendStringInfoSpaces(es->str, es->indent * 2); appendStringInfoSpaces(es->str, es->indent * 2);
appendStringInfoString(es->str, "Buffers:"); appendStringInfoString(es->str, "Total Buffer Usage:");
if (has_shared) 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"); appendStringInfoString(es->str, " shared");
if (usage->shared_blks_hit > 0) appendStringInfo(es->str, " hit=%.*f%s",
appendStringInfo(es->str, " hit=%ld", hit_prec, hit_mem, hit_unit);
usage->shared_blks_hit);
if (usage->shared_blks_read > 0) if (usage->shared_blks_read > 0)
appendStringInfo(es->str, " read=%ld", appendStringInfo(es->str, " read=%.*f%s",
usage->shared_blks_read); read_prec, read_mem, read_unit);
if (usage->shared_blks_written > 0) if (usage->shared_blks_written > 0)
appendStringInfo(es->str, " written=%ld", appendStringInfo(es->str, " written=%.*f%s",
usage->shared_blks_written); written_prec, written_mem, written_unit);
if (has_local || has_temp) if (has_local || has_temp)
appendStringInfoChar(es->str, ','); appendStringInfoChar(es->str, ',');
} }
if (has_local) if (has_local)
{ {
appendStringInfoString(es->str, " local"); char *hit_unit, *read_unit, *written_unit;
if (usage->local_blks_hit > 0) int hit_prec, read_prec, written_prec;
appendStringInfo(es->str, " hit=%ld", double hit_mem = normalize_memory((double)usage->local_blks_hit * BLCKSZ, &hit_unit, &hit_prec);
usage->local_blks_hit); double read_mem = normalize_memory((double)usage->local_blks_read * BLCKSZ, &read_unit, &read_prec);
if (usage->local_blks_read > 0) double written_mem = normalize_memory((double)usage->local_blks_written * BLCKSZ, &written_unit, &written_prec);
appendStringInfo(es->str, " read=%ld",
usage->local_blks_read); appendStringInfoString(es->str, " local");
if (usage->local_blks_written > 0) if (usage->local_blks_hit > 0)
appendStringInfo(es->str, " written=%ld", appendStringInfo(es->str, " hit=%.*f%s",
usage->local_blks_written); 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) if (has_temp)
appendStringInfoChar(es->str, ','); appendStringInfoChar(es->str, ',');
} }
if (has_temp) 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"); appendStringInfoString(es->str, " temp");
if (usage->temp_blks_read > 0) if (usage->temp_blks_read > 0)
appendStringInfo(es->str, " read=%ld", appendStringInfo(es->str, " read=%.*f%s",
usage->temp_blks_read); read_prec, read_mem, read_unit);
if (usage->temp_blks_written > 0) if (usage->temp_blks_written > 0)
appendStringInfo(es->str, " written=%ld", appendStringInfo(es->str, " written=%.*f%s",
usage->temp_blks_written); written_prec, written_mem, written_unit);
} }
appendStringInfoChar(es->str, '\n'); appendStringInfoChar(es->str, '\n');
} }
...@@ -2153,3 +2170,36 @@ escape_yaml(StringInfo buf, const char *str) ...@@ -2153,3 +2170,36 @@ escape_yaml(StringInfo buf, const char *str)
appendStringInfo(buf, "%s", 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment