aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-05-04 21:29:53 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-05-04 21:29:53 +0000
commitd2a4a4069f1677d74267c04d558a8be83a382098 (patch)
tree9ff818c24437a2b3594e75b8ecc2116e2c8edce8 /src
parentc7464720a33240db41a16d3a675d640aa361d7a5 (diff)
downloadpostgresql-d2a4a4069f1677d74267c04d558a8be83a382098.tar.gz
postgresql-d2a4a4069f1677d74267c04d558a8be83a382098.zip
Add a line to the EXPLAIN ANALYZE output for a Sort node, showing the
actual sort strategy and amount of space used. By popular demand.
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/explain.c29
-rw-r--r--src/backend/utils/sort/tuplesort.c64
-rw-r--r--src/include/utils/tuplesort.h4
3 files changed, 94 insertions, 3 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 592eeba4177..608ebf93ce8 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.162 2007/04/27 22:05:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.163 2007/05/04 21:29:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,6 +30,7 @@
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
+#include "utils/tuplesort.h"
typedef struct ExplainState
@@ -58,6 +59,8 @@ static void show_upper_qual(List *qual, const char *qlabel, Plan *plan,
static void show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
const char *qlabel,
StringInfo str, int indent, ExplainState *es);
+static void show_sort_info(SortState *sortstate,
+ StringInfo str, int indent, ExplainState *es);
/*
* ExplainQuery -
@@ -818,6 +821,8 @@ explain_outNode(StringInfo str,
((Sort *) plan)->sortColIdx,
"Sort Key",
str, indent, es);
+ show_sort_info((SortState *) planstate,
+ str, indent, es);
break;
case T_Result:
show_upper_qual((List *) ((Result *) plan)->resconstantqual,
@@ -1123,3 +1128,25 @@ show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
appendStringInfo(str, "\n");
}
+
+/*
+ * If it's EXPLAIN ANALYZE, show tuplesort explain info for a sort node
+ */
+static void
+show_sort_info(SortState *sortstate,
+ StringInfo str, int indent, ExplainState *es)
+{
+ Assert(IsA(sortstate, SortState));
+ if (es->printAnalyze && sortstate->sort_Done &&
+ sortstate->tuplesortstate != NULL)
+ {
+ char *sortinfo;
+ int i;
+
+ sortinfo = tuplesort_explain((Tuplesortstate *) sortstate->tuplesortstate);
+ for (i = 0; i < indent; i++)
+ appendStringInfo(str, " ");
+ appendStringInfo(str, " %s\n", sortinfo);
+ pfree(sortinfo);
+ }
+}
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index e4fc74b3e93..707112d5fb1 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -91,7 +91,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.75 2007/05/04 01:13:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.76 2007/05/04 21:29:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -196,6 +196,7 @@ struct Tuplesortstate
bool randomAccess; /* did caller request random access? */
bool bounded; /* did caller specify a maximum number of
* tuples to return? */
+ bool boundUsed; /* true if we made use of a bounded heap */
int bound; /* if bounded, the maximum number of tuples */
long availMem; /* remaining memory available, in bytes */
long allowedMem; /* total memory allowed, in bytes */
@@ -505,6 +506,8 @@ tuplesort_begin_common(int workMem, bool randomAccess)
state->status = TSS_INITIAL;
state->randomAccess = randomAccess;
+ state->bounded = false;
+ state->boundUsed = false;
state->allowedMem = workMem * 1024L;
state->availMem = state->allowedMem;
state->sortcontext = sortcontext;
@@ -2113,6 +2116,64 @@ tuplesort_restorepos(Tuplesortstate *state)
MemoryContextSwitchTo(oldcontext);
}
+/*
+ * tuplesort_explain - produce a line of information for EXPLAIN ANALYZE
+ *
+ * This can be called after tuplesort_performsort() finishes to obtain
+ * printable summary information about how the sort was performed.
+ *
+ * The result is a palloc'd string.
+ */
+char *
+tuplesort_explain(Tuplesortstate *state)
+{
+ char *result = (char *) palloc(100);
+ long spaceUsed;
+
+ /*
+ * Note: it might seem we should print both memory and disk usage for a
+ * disk-based sort. However, the current code doesn't track memory space
+ * accurately once we have begun to return tuples to the caller (since
+ * we don't account for pfree's the caller is expected to do), so we
+ * cannot rely on availMem in a disk sort. This does not seem worth the
+ * overhead to fix. Is it worth creating an API for the memory context
+ * code to tell us how much is actually used in sortcontext?
+ */
+ if (state->tapeset)
+ spaceUsed = LogicalTapeSetBlocks(state->tapeset) * (BLCKSZ / 1024);
+ else
+ spaceUsed = (state->allowedMem - state->availMem + 1023) / 1024;
+
+ switch (state->status)
+ {
+ case TSS_SORTEDINMEM:
+ if (state->boundUsed)
+ snprintf(result, 100,
+ "Sort Method: top-N heapsort Memory: %ldkB",
+ spaceUsed);
+ else
+ snprintf(result, 100,
+ "Sort Method: quicksort Memory: %ldkB",
+ spaceUsed);
+ break;
+ case TSS_SORTEDONTAPE:
+ snprintf(result, 100,
+ "Sort Method: external sort Disk: %ldkB",
+ spaceUsed);
+ break;
+ case TSS_FINALMERGE:
+ snprintf(result, 100,
+ "Sort Method: external merge Disk: %ldkB",
+ spaceUsed);
+ break;
+ default:
+ snprintf(result, 100, "sort still in progress");
+ break;
+ }
+
+ return result;
+}
+
/*
* Heap manipulation routines, per Knuth's Algorithm 5.2.3H.
@@ -2216,6 +2277,7 @@ sort_bounded_heap(Tuplesortstate *state)
REVERSEDIRECTION(state);
state->status = TSS_SORTEDINMEM;
+ state->boundUsed = true;
}
/*
diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h
index c736896a9a9..b522c3ef7b6 100644
--- a/src/include/utils/tuplesort.h
+++ b/src/include/utils/tuplesort.h
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/tuplesort.h,v 1.26 2007/05/04 01:13:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/tuplesort.h,v 1.27 2007/05/04 21:29:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -74,6 +74,8 @@ extern bool tuplesort_getdatum(Tuplesortstate *state, bool forward,
extern void tuplesort_end(Tuplesortstate *state);
+extern char *tuplesort_explain(Tuplesortstate *state);
+
extern int tuplesort_merge_order(long allowedMem);
/*