The other thing that emerged from http://www.postgresql.org/message-id/flat/CAOR=d=3j1U_q-zf8+jUx1hkx8ps+N8pm=EUTqyFdJ5ov=+f...@mail.gmail.com is that for workloads like this, OverrideSearchPathMatchesCurrent is a bottleneck: it's part of the code path needed to re-use a cached plan, and this example is doing a lot of that. The original implementation of that function followed the KISS principle, since I thought it probably wouldn't be a bottleneck. Now that that's proven wrong, I offer the attached reimplementation, which saves about 9% of overall runtime on Scott's example by avoiding palloc/pfree traffic. It knows a lot more about the relation of override search paths to active search paths than it did before; but the adjacent functions know these things too, so it doesn't seem like much of a loss from a maintainability standpoint.
regards, tom lane
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 911f015..7a06332 100644 *** a/src/backend/catalog/namespace.c --- b/src/backend/catalog/namespace.c *************** CopyOverrideSearchPath(OverrideSearchPat *** 3145,3164 **** bool OverrideSearchPathMatchesCurrent(OverrideSearchPath *path) { ! /* Easiest way to do this is GetOverrideSearchPath() and compare */ ! bool result; ! OverrideSearchPath *cur; ! cur = GetOverrideSearchPath(CurrentMemoryContext); ! if (path->addCatalog == cur->addCatalog && ! path->addTemp == cur->addTemp && ! equal(path->schemas, cur->schemas)) ! result = true; ! else ! result = false; ! list_free(cur->schemas); ! pfree(cur); ! return result; } /* --- 3145,3188 ---- bool OverrideSearchPathMatchesCurrent(OverrideSearchPath *path) { ! ListCell *lc, ! *lcp; ! recomputeNamespacePath(); ! ! /* We scan down the activeSearchPath to see if it matches the input. */ ! lc = list_head(activeSearchPath); ! ! /* If path->addTemp, first item should be my temp namespace. */ ! if (path->addTemp) ! { ! if (lc && lfirst_oid(lc) == myTempNamespace) ! lc = lnext(lc); ! else ! return false; ! } ! /* If path->addCatalog, next item should be pg_catalog. */ ! if (path->addCatalog) ! { ! if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE) ! lc = lnext(lc); ! else ! return false; ! } ! /* We should now be looking at the activeCreationNamespace. */ ! if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid)) ! return false; ! /* The remainder of activeSearchPath should match path->schemas. */ ! foreach(lcp, path->schemas) ! { ! if (lc && lfirst_oid(lc) == lfirst_oid(lcp)) ! lc = lnext(lc); ! else ! return false; ! } ! if (lc) ! return false; ! return true; } /*
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers