]> granicus.if.org Git - postgresql/commitdiff
Fix O(N^2) behavior in pg_dump for large numbers of owned sequences.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 31 Mar 2012 18:42:17 +0000 (14:42 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 31 Mar 2012 18:42:17 +0000 (14:42 -0400)
The loop that matched owned sequences to their owning tables required time
proportional to number of owned sequences times number of tables; although
this work was only expended in selective-dump situations, which is probably
why the issue wasn't recognized long since.  Refactor slightly so that we
can perform this work after the index array for findTableByOid has been
set up, reducing the time to O(M log N).

Per gripe from Mike Roest.  Since this is a longstanding performance bug,
backpatch to all supported versions.

src/bin/pg_dump/common.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h

index db48ccb41915c4bbd85afbbb85ed04f8f9b59686..9ec180decad1bce2f08024c28da3457c2c4ebfd1 100644 (file)
@@ -114,6 +114,9 @@ getSchemaData(Archive *fout, int *numTablesPtr)
        tblinfo = getTables(fout, &numTables);
        tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo));
 
+       /* Do this after we've built tblinfoindex */
+       getOwnedSeqs(fout, tblinfo, numTables);
+
        if (g_verbose)
                write_msg(NULL, "reading extensions\n");
        extinfo = getExtensions(fout, &numExtensions);
index 14389bd0d37293427b67c2b3d6608121991fe89c..f9fbaeeb5e8de0a17ca91b516242b21977bfaa5a 100644 (file)
@@ -4307,38 +4307,43 @@ getTables(Archive *fout, int *numTables)
 
        PQclear(res);
 
+       destroyPQExpBuffer(query);
+
+       return tblinfo;
+}
+
+/*
+ * getOwnedSeqs
+ *       identify owned sequences and mark them as dumpable if owning table is
+ *
+ * We used to do this in getTables(), but it's better to do it after the
+ * index used by findTableByOid() has been set up.
+ */
+void
+getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
+{
+       int                     i;
+
        /*
         * Force sequences that are "owned" by table columns to be dumped whenever
         * their owning table is being dumped.
         */
-       for (i = 0; i < ntups; i++)
+       for (i = 0; i < numTables; i++)
        {
                TableInfo  *seqinfo = &tblinfo[i];
-               int                     j;
+               TableInfo  *owning_tab;
 
                if (!OidIsValid(seqinfo->owning_tab))
                        continue;                       /* not an owned sequence */
                if (seqinfo->dobj.dump)
                        continue;                       /* no need to search */
-
-               /* can't use findTableByOid yet, unfortunately */
-               for (j = 0; j < ntups; j++)
+               owning_tab = findTableByOid(seqinfo->owning_tab);
+               if (owning_tab && owning_tab->dobj.dump)
                {
-                       if (tblinfo[j].dobj.catId.oid == seqinfo->owning_tab)
-                       {
-                               if (tblinfo[j].dobj.dump)
-                               {
-                                       seqinfo->interesting = true;
-                                       seqinfo->dobj.dump = true;
-                               }
-                               break;
-                       }
+                       seqinfo->interesting = true;
+                       seqinfo->dobj.dump = true;
                }
        }
-
-       destroyPQExpBuffer(query);
-
-       return tblinfo;
 }
 
 /*
index 28a7fe4e130977627eaba67991bd455b0c3cd449..fba69532ab2611e112971b4a766043c8f14d5071 100644 (file)
@@ -538,6 +538,7 @@ extern OpfamilyInfo *getOpfamilies(Archive *fout, int *numOpfamilies);
 extern CollInfo *getCollations(Archive *fout, int *numCollations);
 extern ConvInfo *getConversions(Archive *fout, int *numConversions);
 extern TableInfo *getTables(Archive *fout, int *numTables);
+extern void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables);
 extern InhInfo *getInherits(Archive *fout, int *numInherits);
 extern void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables);
 extern void getConstraints(Archive *fout, TableInfo tblinfo[], int numTables);