|
7 | 7 | * Portions Copyright (c) 1994-5, Regents of the University of California
|
8 | 8 | *
|
9 | 9 | * IDENTIFICATION
|
10 |
| - * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.200 2010/02/01 15:43:35 rhaas Exp $ |
| 10 | + * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.201 2010/02/15 02:36:26 stark Exp $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
@@ -98,6 +98,7 @@ static void ExplainJSONLineEnding(ExplainState *es);
|
98 | 98 | static void ExplainYAMLLineStarting(ExplainState *es);
|
99 | 99 | static void escape_json(StringInfo buf, const char *str);
|
100 | 100 | static void escape_yaml(StringInfo buf, const char *str);
|
| 101 | +static double normalize_memory(double amount, char **unit, int *precision); |
101 | 102 |
|
102 | 103 |
|
103 | 104 | /*
|
@@ -1081,47 +1082,63 @@ ExplainNode(Plan *plan, PlanState *planstate,
|
1081 | 1082 | if (has_shared || has_local || has_temp)
|
1082 | 1083 | {
|
1083 | 1084 | appendStringInfoSpaces(es->str, es->indent * 2);
|
1084 |
| - appendStringInfoString(es->str, "Buffers:"); |
| 1085 | + appendStringInfoString(es->str, "Total Buffer Usage:"); |
1085 | 1086 |
|
1086 | 1087 | if (has_shared)
|
1087 | 1088 | {
|
| 1089 | + char *hit_unit, *read_unit, *written_unit; |
| 1090 | + int hit_prec, read_prec, written_prec; |
| 1091 | + double hit_mem = normalize_memory((double)usage->shared_blks_hit * BLCKSZ, &hit_unit, &hit_prec); |
| 1092 | + double read_mem = normalize_memory((double)usage->shared_blks_read * BLCKSZ, &read_unit, &read_prec); |
| 1093 | + double written_mem = normalize_memory((double)usage->shared_blks_written * BLCKSZ, &written_unit, &written_prec); |
| 1094 | + |
1088 | 1095 | appendStringInfoString(es->str, " shared");
|
1089 |
| - if (usage->shared_blks_hit > 0) |
1090 |
| - appendStringInfo(es->str, " hit=%ld", |
1091 |
| - usage->shared_blks_hit); |
| 1096 | + appendStringInfo(es->str, " hit=%.*f%s", |
| 1097 | + hit_prec, hit_mem, hit_unit); |
1092 | 1098 | if (usage->shared_blks_read > 0)
|
1093 |
| - appendStringInfo(es->str, " read=%ld", |
1094 |
| - usage->shared_blks_read); |
| 1099 | + appendStringInfo(es->str, " read=%.*f%s", |
| 1100 | + read_prec, read_mem, read_unit); |
1095 | 1101 | if (usage->shared_blks_written > 0)
|
1096 |
| - appendStringInfo(es->str, " written=%ld", |
1097 |
| - usage->shared_blks_written); |
| 1102 | + appendStringInfo(es->str, " written=%.*f%s", |
| 1103 | + written_prec, written_mem, written_unit); |
1098 | 1104 | if (has_local || has_temp)
|
1099 | 1105 | appendStringInfoChar(es->str, ',');
|
1100 | 1106 | }
|
1101 | 1107 | if (has_local)
|
1102 | 1108 | {
|
1103 |
| - appendStringInfoString(es->str, " local"); |
1104 |
| - if (usage->local_blks_hit > 0) |
1105 |
| - appendStringInfo(es->str, " hit=%ld", |
1106 |
| - usage->local_blks_hit); |
1107 |
| - if (usage->local_blks_read > 0) |
1108 |
| - appendStringInfo(es->str, " read=%ld", |
1109 |
| - usage->local_blks_read); |
1110 |
| - if (usage->local_blks_written > 0) |
1111 |
| - appendStringInfo(es->str, " written=%ld", |
1112 |
| - usage->local_blks_written); |
| 1109 | + char *hit_unit, *read_unit, *written_unit; |
| 1110 | + int hit_prec, read_prec, written_prec; |
| 1111 | + double hit_mem = normalize_memory((double)usage->local_blks_hit * BLCKSZ, &hit_unit, &hit_prec); |
| 1112 | + double read_mem = normalize_memory((double)usage->local_blks_read * BLCKSZ, &read_unit, &read_prec); |
| 1113 | + double written_mem = normalize_memory((double)usage->local_blks_written * BLCKSZ, &written_unit, &written_prec); |
| 1114 | + |
| 1115 | + appendStringInfoString(es->str, " local"); |
| 1116 | + if (usage->local_blks_hit > 0) |
| 1117 | + appendStringInfo(es->str, " hit=%.*f%s", |
| 1118 | + hit_prec, hit_mem, hit_unit); |
| 1119 | + if (usage->local_blks_read > 0) |
| 1120 | + appendStringInfo(es->str, " read=%.*f%s", |
| 1121 | + read_prec, read_mem, read_unit); |
| 1122 | + if (usage->local_blks_written > 0) |
| 1123 | + appendStringInfo(es->str, " written=%.*f%s", |
| 1124 | + written_prec, written_mem, written_unit); |
1113 | 1125 | if (has_temp)
|
1114 | 1126 | appendStringInfoChar(es->str, ',');
|
1115 | 1127 | }
|
1116 | 1128 | if (has_temp)
|
1117 | 1129 | {
|
| 1130 | + char *read_unit, *written_unit; |
| 1131 | + int read_prec, written_prec; |
| 1132 | + double read_mem = normalize_memory((double)usage->temp_blks_read * BLCKSZ, &read_unit, &read_prec); |
| 1133 | + double written_mem = normalize_memory((double)usage->temp_blks_written * BLCKSZ, &written_unit, &written_prec); |
| 1134 | + |
1118 | 1135 | appendStringInfoString(es->str, " temp");
|
1119 | 1136 | if (usage->temp_blks_read > 0)
|
1120 |
| - appendStringInfo(es->str, " read=%ld", |
1121 |
| - usage->temp_blks_read); |
1122 |
| - if (usage->temp_blks_written > 0) |
1123 |
| - appendStringInfo(es->str, " written=%ld", |
1124 |
| - usage->temp_blks_written); |
| 1137 | + appendStringInfo(es->str, " read=%.*f%s", |
| 1138 | + read_prec, read_mem, read_unit); |
| 1139 | + if (usage->temp_blks_written > 0) |
| 1140 | + appendStringInfo(es->str, " written=%.*f%s", |
| 1141 | + written_prec, written_mem, written_unit); |
1125 | 1142 | }
|
1126 | 1143 | appendStringInfoChar(es->str, '\n');
|
1127 | 1144 | }
|
@@ -2153,3 +2170,36 @@ escape_yaml(StringInfo buf, const char *str)
|
2153 | 2170 |
|
2154 | 2171 | appendStringInfo(buf, "%s", str);
|
2155 | 2172 | }
|
| 2173 | + |
| 2174 | +/* |
| 2175 | + * For a quantity of bytes pick a reasonable display unit for it and |
| 2176 | + * return the quantity in that unit. Also return the unit name and a |
| 2177 | + * reasonable precision via the reference parameters. |
| 2178 | + */ |
| 2179 | + |
| 2180 | +static double normalize_memory(double amount, char **unit, int *precision) |
| 2181 | +{ |
| 2182 | + static char *units[] = {"bytes", "kB", "MB", "GB", "TB", "PB"}; |
| 2183 | + char **u = units, **last = units + (sizeof(units)/sizeof(*units)-1); |
| 2184 | + |
| 2185 | + while (amount > 1024.0 && u < last) |
| 2186 | + { |
| 2187 | + amount /= 1024.0; |
| 2188 | + u += 1; |
| 2189 | + } |
| 2190 | + |
| 2191 | + *unit = *u; |
| 2192 | + |
| 2193 | + /* if it's bytes or kB then don't print decimals since that's less |
| 2194 | + * than blocksize, otherwise always print 3 significant digits */ |
| 2195 | + if (u == units || u == units+1 ) |
| 2196 | + *precision = 0; |
| 2197 | + else if (amount < 10) |
| 2198 | + *precision = 2; |
| 2199 | + else if (amount < 100) |
| 2200 | + *precision = 1; |
| 2201 | + else |
| 2202 | + *precision = 0; |
| 2203 | + |
| 2204 | + return amount; |
| 2205 | +} |
0 commit comments