psql microsecond timing patch - Mailing list pgsql-patches

From greg@turnstep.com
Subject psql microsecond timing patch
Date
Msg-id 200109271535.LAA00608@barry.mail.mindspring.net
Whole thread Raw
Responses Re: psql microsecond timing patch  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-patches
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This is a small patch to allow you to time your queries in
psql. Myself and some others have been using it and find it
useful for telling how long an actual specific query takes,
as opposed to EXPLAIN which just does an estimate. Using the
two together is a good way to tweak sql and indices. Even
if not deemed useful, it should be good practice in learning
to submit patches. :)

(I called it "microsecond timing" because "m" was one of the
few letters still available as a backslash command that
had some mnemonic potential.)

Thanks,
Greg Sabino Mullane
greg@turnstep.com 200109270943
PGP Key: 0x14964AC8

-----BEGIN PGP SIGNATURE-----
Comment: http://www.turnstep.com/pgp.html

iQA/AwUBO7NHE7ybkGcUlkrIEQIq9wCfSSsozUx5U55EPUsuBz5XZErfcIEAnAu7
FrtN+K+rtXIgTmRn9MABLC3i
=UXkx
-----END PGP SIGNATURE-----
*** ./src/bin/psql/command.c.orig    Sun Sep 16 21:07:53 2001
--- ./src/bin/psql/command.c    Sun Sep 16 20:13:08 2001
***************
*** 521,526 ****
--- 521,529 ----
          free(opt2);
      }

+     /* \m -- toggle microsecond timing of queries */
+     else if (strcmp(cmd, "m") == 0)
+         success = do_pset("microtiming", NULL, &pset.popt, quiet);

      /* \o -- set query output */
      else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
***************
*** 1751,1756 ****
--- 1754,1771 ----
          }
      }

+     /* toggle showing of query speed */
+     else if (strcmp(param, "m") == 0 || strcmp(param, "microtiming") == 0)
+     {
+         popt->topt.microtiming = !popt->topt.microtiming;
+         if (!quiet)
+         {
+             if (popt->topt.microtiming)
+                 puts("Microsecond timing is on.");
+             else
+                 puts("Microsecond timing is off.");
+         }
+     }

      else
      {
*** ./src/bin/psql/common.c.orig    Sun Sep 16 21:07:53 2001
--- ./src/bin/psql/common.c    Mon Sep 24 12:22:26 2001
***************
*** 11,16 ****
--- 11,17 ----

  #include <errno.h>
  #include <stdarg.h>
+ #include <sys/time.h>
  #ifdef HAVE_TERMIOS_H
  #include <termios.h>
  #endif
***************
*** 377,382 ****
--- 378,385 ----
      bool        success = false;
      PGresult   *results;
      PGnotify   *notify;
+     struct timeval before,after;
+     struct timezone tz;

      if (!pset.db)
      {
***************
*** 406,412 ****
--- 409,419 ----
      }

      cancelConn = pset.db;
+
+     if (pset.popt.topt.microtiming) { gettimeofday(&before, &tz); }
      results = PQexec(pset.db, query);
+     if (pset.popt.topt.microtiming) { gettimeofday(&after, &tz); }
+
      if (PQresultStatus(results) == PGRES_COPY_IN)
          copy_in_state = true;
      /* keep cancel connection for copy out state */
***************
*** 534,539 ****
--- 541,551 ----

          if (results)
              PQclear(results);
+     }
+
+     /* Possible microtiming output */
+     if (pset.popt.topt.microtiming  && success) {
+         printf("TOTAL TIME: %f\n",((after.tv_sec-before.tv_sec)*1000000 + after.tv_usec - before.tv_usec) /
1000000.0);
      }

      return success;
*** ./src/bin/psql/help.c.orig    Sun Sep 16 21:07:53 2001
--- ./src/bin/psql/help.c    Sun Sep 16 20:13:10 2001
***************
*** 218,223 ****
--- 218,224 ----
      fprintf(fout, " \\l             list all databases\n");
      fprintf(fout, " \\lo_export, \\lo_import, \\lo_list, \\lo_unlink\n"
              "                large object operations\n");
+     fprintf(fout, " \\m             toggle microsecond timing of queries (currently %s)\n",
ON(pset.popt.topt.microtiming));
      fprintf(fout, " \\o [file]      send all query results to [file], or |pipe\n");
      fprintf(fout, " \\p             show the content of the current query buffer\n");
      fprintf(fout, " \\pset <opt>    set table output  <opt> = {format|border|expanded|fieldsep|\n"
*** ./src/bin/psql/print.h.orig    Mon Sep 24 11:59:33 2001
--- ./src/bin/psql/print.h    Mon Sep 24 12:24:28 2001
***************
*** 35,40 ****
--- 35,41 ----
      char       *recordSep;        /* record separator for unaligned text
                                   * mode */
      char       *tableAttr;        /* attributes for HTML <table ...> */
+     bool        microtiming;    /* show query time in microseconds */
  } printTableOpt;


*** ./src/bin/psql/startup.c.orig    Sun Sep 16 21:07:53 2001
--- ./src/bin/psql/startup.c    Mon Sep 24 12:26:52 2001
***************
*** 332,337 ****
--- 332,338 ----
          {"host", required_argument, NULL, 'h'},
          {"html", no_argument, NULL, 'H'},
          {"list", no_argument, NULL, 'l'},
+         {"microtiming", no_argument, NULL, 'm'},
          {"no-readline", no_argument, NULL, 'n'},
          {"output", required_argument, NULL, 'o'},
          {"port", required_argument, NULL, 'p'},
***************
*** 364,377 ****
      memset(options, 0, sizeof *options);

  #ifdef HAVE_GETOPT_LONG
!     while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:h:Hlno:p:P:qR:sStT:uU:v:VWxX?", long_options, &optindex)) != -1)
  #else                            /* not HAVE_GETOPT_LONG */

      /*
       * Be sure to leave the '-' in here, so we can catch accidental long
       * options.
       */
!     while ((c = getopt(argc, argv, "aAc:d:eEf:F:h:Hlno:p:P:qR:sStT:uU:v:VWxX?-")) != -1)
  #endif     /* not HAVE_GETOPT_LONG */
      {
          switch (c)
--- 365,378 ----
      memset(options, 0, sizeof *options);

  #ifdef HAVE_GETOPT_LONG
!     while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:h:Hlmno:p:P:qR:sStT:uU:v:VWxX?", long_options, &optindex)) !=
-1)
  #else                            /* not HAVE_GETOPT_LONG */

      /*
       * Be sure to leave the '-' in here, so we can catch accidental long
       * options.
       */
!     while ((c = getopt(argc, argv, "aAc:d:eEf:F:h:Hlmno:p:P:qR:sStT:uU:v:VWxX?-")) != -1)
  #endif     /* not HAVE_GETOPT_LONG */
      {
          switch (c)
***************
*** 416,421 ****
--- 417,425 ----
                  break;
              case 'l':
                  options->action = ACT_LIST_DB;
+                 break;
+             case 'm':
+                 pset.popt.topt.microtiming = true;
                  break;
              case 'n':
                  options->no_readline = true;
*** ./src/bin/psql/tab-complete.c.orig    Sun Sep 16 21:07:53 2001
--- ./src/bin/psql/tab-complete.c    Sun Sep 16 20:13:13 2001
***************
*** 260,266 ****
      static char *backslash_commands[] = {
          "\\connect", "\\copy", "\\d", "\\di", "\\di", "\\ds", "\\dS", "\\dv",
          "\\da", "\\df", "\\do", "\\dt", "\\e", "\\echo", "\\encoding",
!         "\\g", "\\h", "\\i", "\\l",
          "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
          "\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\unset",
          "\\x", "\\w", "\\z", "\\!", NULL
--- 260,266 ----
      static char *backslash_commands[] = {
          "\\connect", "\\copy", "\\d", "\\di", "\\di", "\\ds", "\\dS", "\\dv",
          "\\da", "\\df", "\\do", "\\dt", "\\e", "\\echo", "\\encoding",
!         "\\g", "\\h", "\\i", "\\l", "\\m",
          "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
          "\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\unset",
          "\\x", "\\w", "\\z", "\\!", NULL
***************
*** 719,726 ****
          COMPLETE_WITH_LIST(sql_commands);
      else if (strcmp(prev_wd, "\\pset") == 0)
      {
!         char       *my_list[] = {"format", "border", "expanded", "null", "fieldsep",
!             "tuples_only", "title", "tableattr", "pager",
          "recordsep", NULL};

          COMPLETE_WITH_LIST(my_list);
--- 719,727 ----
          COMPLETE_WITH_LIST(sql_commands);
      else if (strcmp(prev_wd, "\\pset") == 0)
      {
!         char       *my_list[] = {"format", "border", "expanded", "microtiming",
!                                  "null", "fieldsep","tuples_only", "title",
!                                  "tableattr", "pager",
          "recordsep", NULL};

          COMPLETE_WITH_LIST(my_list);
*** ./doc/src/sgml/ref/psql-ref.sgml.orig    Thu Sep 27 09:03:20 2001
--- ./doc/src/sgml/ref/psql-ref.sgml    Thu Sep 27 09:02:26 2001
***************
*** 738,743 ****
--- 738,758 ----


        <varlistentry>
+         <term><literal>\m</literal></term>
+         <listitem>
+         <para>
+         This toggles a display of how long each query takes to complete
+         in seconds, down to a microsecond resolution. This uses your
+         system's <command>gettimeofday</command> function to get an
+         approximate measurement of how long a query takes to run. This is
+         useful as a way to measure the relative speeds of different queries
+         as you tweak the SQL and indices.
+         </para>
+         </listitem>
+       </varlistentry>
+
+
+       <varlistentry>
          <term><literal>\o</literal> [ {<replaceable class="parameter">filename</replaceable> |
<literal>|</literal><replaceableclass="parameter">command</replaceable>} ]</term> 

          <listitem>

pgsql-patches by date:

Previous
From: "Serguei Mokhov"
Date:
Subject: NLS for POSTGRESQL (Russian)
Next
From: Karel Zak
Date:
Subject: Re: Problem with setlocale (found in libecpg) [accessing a memory location after freeing it]