Re: Faster "SET search_path"

From: Jeff Davis <pgsql(at)j-davis(dot)com>
To: Isaac Morland <isaac(dot)morland(at)gmail(dot)com>, Nathan Bossart <nathandbossart(at)gmail(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Faster "SET search_path"
Date: 2023-08-07 19:57:27
Message-ID: fec7f3bea50112323d9b6e700b5e2762a14af809.camel@j-davis.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, 2023-08-02 at 01:14 -0400, Isaac Morland wrote:
> > > On Sat, 2023-07-29 at 12:44 -0400, Isaac Morland wrote:
> > > > Essentially, "just" observe efficiently (somehow) that no
> > > > change is
> > > > needed, and skip changing it?

...

> Speaking as someone who uses a lot of stored procedures, many of
> which call one another, I definitely want this optimization.

If we try to avoid the set_config_option() entirely, we'd have to
introduce the invalidation logic into fmgr.c somehow, and there would
be a performance cliff for users who change their session's
search_path.

Instead, in v4 (attached) I introduced a fast path (patch 0004,
experimental) for setting search_path that uses the same low-level
invalidation logic in namespace.c, but avoids most of the overhead of
set_config_option().

(Aside: part of the reason set_config_option() is slow is because of
the lookup in guc_hashtab. That's slower than some other hash lookups
because it does case-folding, which needs to be done in both the hash
function and also the match function. The hash lookups in
SearchPathCache are significantly faster. I also have a patch to change
guc_hashtab to simplehash, but I didn't see much difference.)

New timings (with session's search_path set to a, b):

inc() plain function: 4.1s
inc_secdef() SECURITY DEFINER: 4.3s
inc_wm() SET work_mem = '4GB': 6.3s
inc_ab() SET search_path = a, b: 5.4s
inc_bc() SET search_path = b, c: 5.6s

I reported the numbers a bit differently here. All numbers are using v4
of the patch. The plain function is a baseline; SECURITY DEFINER is for
measuring the overhead of the fmgr_security_definer wrapper; inc_ab()
is for setting the search_path to the same value it's already set to;
and inc_bc() is for setting the search_path to a new value.

There's still a difference between inc() (with no proconfigs) and
inc_ab(), so you can certainly argue that some or all of that can be
avoided if the search_path is unchanged. For instance, adding the new
GUC level causes AtEOXact_GUC to be run, and that does some work. Maybe
it's even possible to avoid the fmgr_security_definer wrapper entirely
(though it would be tricky to do so).

But in general I'd prefer to optimize cases that are going to work
nicely by default for a lot of users (especially switching to a safe
search path), without the need for obscure knowledge about the
performance implications of the session search_path. And to the extent
that we do optimize for the pre-existing search_path, I'd like to
understand the inherent overhead of changing the search path versus
incidental overhead.

--
Jeff Davis
PostgreSQL Contributor Team - AWS

Attachment Content-Type Size
v4-0001-Transform-proconfig-for-faster-execution.patch text/x-patch 5.8 KB
v4-0002-Optimize-check_search_path.patch text/x-patch 4.3 KB
v4-0003-Add-cache-for-recomputeNamespacePath.patch text/x-patch 17.2 KB
v4-0004-wip.patch text/x-patch 4.5 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Dave Cramer 2023-08-07 20:00:25 Re: Using defines for protocol characters
Previous Message Tomas Vondra 2023-08-07 19:48:16 Re: Configurable FP_LOCK_SLOTS_PER_BACKEND