On Sun, 2005-10-02 at 19:43 +0100, Simon Riggs wrote: > The following patch implements a fairly light set of timing statements > aimed at understanding external sort performance. There is no attempt to > alter the algorithms.
Minor update of patch, use this version please. > Best Regards, Simon Riggs
Index: src/backend/utils/misc/guc.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v retrieving revision 1.289 diff -c -c -r1.289 guc.c *** src/backend/utils/misc/guc.c 24 Sep 2005 22:54:39 -0000 1.289 --- src/backend/utils/misc/guc.c 2 Oct 2005 19:58:02 -0000 *************** *** 92,97 **** --- 92,98 ---- extern int CommitSiblings; extern char *default_tablespace; extern bool fullPageWrites; + extern bool debug_sort; static const char *assign_log_destination(const char *value, bool doit, GucSource source); *************** *** 764,770 **** false, NULL, NULL }, #endif ! { {"log_hostname", PGC_SIGHUP, LOGGING_WHAT, gettext_noop("Logs the host name in the connection logs."), --- 765,779 ---- false, NULL, NULL }, #endif ! { ! {"debug_sort", PGC_USERSET, DEVELOPER_OPTIONS, ! gettext_noop("no description available"), ! NULL, ! GUC_NOT_IN_SAMPLE ! }, ! &debug_sort, ! false, NULL, NULL ! }, { {"log_hostname", PGC_SIGHUP, LOGGING_WHAT, gettext_noop("Logs the host name in the connection logs."), Index: src/backend/utils/sort/tuplesort.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v retrieving revision 1.50 diff -c -c -r1.50 tuplesort.c *** src/backend/utils/sort/tuplesort.c 23 Sep 2005 15:36:57 -0000 1.50 --- src/backend/utils/sort/tuplesort.c 2 Oct 2005 19:58:02 -0000 *************** *** 85,90 **** --- 85,92 ---- #include "postgres.h" + #include <sys/time.h> + #include "access/heapam.h" #include "access/nbtree.h" #include "catalog/pg_amop.h" *************** *** 394,399 **** --- 396,404 ---- */ static Tuplesortstate *qsort_tuplesortstate; + /* debug variables */ + bool debug_sort = false; + struct timeval start_t, current_t; /* * tuplesort_begin_xxx *************** *** 422,427 **** --- 427,439 ---- state = (Tuplesortstate *) palloc0(sizeof(Tuplesortstate)); + if (debug_sort) + { + ereport(NOTICE, + (errmsg("tuplesort begin work_mem= %u", workMem))); + gettimeofday(&start_t, NULL); + } + state->status = TSS_INITIAL; state->randomAccess = randomAccess; state->availMem = workMem * 1024L; *************** *** 454,459 **** --- 466,475 ---- Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess); int i; + if (debug_sort) + ereport(NOTICE, + (errmsg("+0 secs heap sort nkeys= %u", nkeys))); + AssertArg(nkeys > 0); state->comparetup = comparetup_heap; *************** *** 499,504 **** --- 515,524 ---- { Tuplesortstate *state = tuplesort_begin_common(workMem, randomAccess); + if (debug_sort) + ereport(NOTICE, + (errmsg("+0 secs index sort"))); + state->comparetup = comparetup_index; state->copytup = copytup_index; state->writetup = writetup_index; *************** *** 666,671 **** --- 686,698 ---- /* * Nope; time to switch to tape-based operation. */ + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs switching to external sort", + (long) (current_t.tv_sec - start_t.tv_sec)))); + } inittapes(state); /* *************** *** 1042,1047 **** --- 1069,1082 ---- int j; int a; + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs starting build of next run", + (long) (current_t.tv_sec - start_t.tv_sec)))); + } + /* Step D3: advance j (destTape) */ if (state->tp_dummy[state->destTape] < state->tp_dummy[state->destTape + 1]) { *************** *** 1082,1087 **** --- 1117,1131 ---- Assert(state->status == TSS_BUILDRUNS); Assert(state->memtupcount == 0); + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs run building complete nruns= %u", + (long) (current_t.tv_sec - start_t.tv_sec), + state->currentRun))); + } + /* * If we produced only one initial run (quite likely if the total data * volume is between 1X and 2X workMem), we can just use that tape as *************** *** 1093,1100 **** --- 1137,1158 ---- /* must freeze and rewind the finished output tape */ LogicalTapeFreeze(state->tapeset, state->result_tape); state->status = TSS_SORTEDONTAPE; + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs no final merge required", + (long) (current_t.tv_sec - start_t.tv_sec)))); + } return; } + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs merging runs with 6 tapes", + (long) (current_t.tv_sec - start_t.tv_sec)))); + } /* End of step D2: rewind all output tapes to prepare for merging */ for (tapenum = 0; tapenum < TAPERANGE; tapenum++) *************** *** 1126,1131 **** --- 1184,1196 ---- /* Initialize for the final merge pass */ beginmerge(state); state->status = TSS_FINALMERGE; + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs starting final merge", + (long) (current_t.tv_sec - start_t.tv_sec)))); + } return; } if (allDummy) *************** *** 1177,1182 **** --- 1242,1254 ---- state->result_tape = state->tp_tapenum[TAPERANGE]; LogicalTapeFreeze(state->tapeset, state->result_tape); state->status = TSS_SORTEDONTAPE; + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs starting final merge", + (long) (current_t.tv_sec - start_t.tv_sec)))); + } } /* *************** *** 1243,1248 **** --- 1315,1327 ---- */ markrunend(state, destTape); state->tp_runs[TAPERANGE]++; + if (debug_sort) + { + gettimeofday(¤t_t, NULL); + ereport(NOTICE, + (errmsg("+%ld secs intermediate merge", + (long) (current_t.tv_sec - start_t.tv_sec)))); + } } /*
---------------------------(end of broadcast)--------------------------- TIP 1: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly