Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wCDyk-001mCo-1L for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 09:53:15 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wCDyh-0069D8-1O for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 09:53:12 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wCDyg-0069D0-2u for pgsql-hackers@lists.postgresql.org; Mon, 13 Apr 2026 09:53:12 +0000 Received: from mail-yx1-xb12f.google.com ([2607:f8b0:4864:20::b12f]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wCDyf-00000000mF8-0uTc for pgsql-hackers@lists.postgresql.org; Mon, 13 Apr 2026 09:53:10 +0000 Received: by mail-yx1-xb12f.google.com with SMTP id 956f58d0204a3-651ce87d785so77388d50.2 for ; Mon, 13 Apr 2026 02:53:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776073989; cv=none; d=google.com; s=arc-20240605; b=PPIEbVI6e1R85jxfMe3rbIhuJMX8ywCy5L+T280xwV1vewexjqzJtMvtAKifM781Iw ZhM97IVZRvjrBqfL4RU9YifA5J+o7B1G/iVmQAXYL64GBiw5aCreR2ic+O5Xid5i1SIj L89/n1B210KXBpkT+oF7K+L82aIFzcYlsjmg4Xp9ct5CFm5zrA74VfpxNSwvhHhresd7 xf3YooiDL9PEwg3ccbCVI6liksF+S//HRcnl65y9/+SZfu4ZCL+aXVblm2vc5Aiekna5 qOfPRGYlYxUVjy5G0njFWTfMHSja7cnwsbvSCztwo4cab7Cg2YXYUrDPnSUMI1PdLlOD G4HQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=iMGBCJ9IEM/oYRqTCMcvMHw+ot5z5JQX0QOhRPXPgms=; fh=wb9NqnYQimSGVvxgRUtQskkilZUMkEI7NNKqWcZGqa4=; b=fhhu8VPpO821dUdJySNrgsytLIfzqeQsICdSRcZN4UoCxNtMx4qstrTWD/w/hFChtJ I1cDtVHyBjzdFyOt0lp4doFqUgj+9h0p79LICEk+kz4W0LqgDNIg+r7UgMvu77B6dn8j Zoa99GwpOE4Mud/Cv7vBiar9KUSd/Ujz0HRbMophk7ZmyyPTF8BNMCyvzEkBekZrubnC VpqnqvsETnKK0p0V12Tjsxk3UYF4ugfXoUyWqD+gQkEtfYdHpc4hiOcF6CcRWjzZEkMQ iLZXzNNKWEMEjkiwDZIp/ck2AkRMuKIa4QzSBu4/XiIpYhmF7i827vQQpulLvvdwm4s+ wIKw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776073989; x=1776678789; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=iMGBCJ9IEM/oYRqTCMcvMHw+ot5z5JQX0QOhRPXPgms=; b=BSVIXK8eew6K2WG/STsMjWZ99znX/57O+cg0XmYVekSSG/2/pj/eOtdacHyyngL5VE K24rTWI1mW54Mi9v5Hu5dbvq/ZpDo9HQywAO8rLs08OoL53u36mvRhcznlIGPp2GOQfG vkW8Qlro+0nU/7mcOp5pG94OCx1ZuMPq1VV1H5JiMShsXSOnSrySPNKCeKia1f6/OerJ OLqT4OXeNtPWgZD9XEaRBkuvZstpLNm216QtcLEwd5vlTCqVimFgL1tg3PhlvDlieg+R nCOYGUw+bzlnqfjzNi1Msu+9AALcjCPsBeUVVh4CEfQ8d+1X9R0ulpbVlPDcBMR84RpW 8a/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776073989; x=1776678789; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=iMGBCJ9IEM/oYRqTCMcvMHw+ot5z5JQX0QOhRPXPgms=; b=jbbwxDSNM9fINJ/uF2yb6dajd7r2v3Y24Hq3GWrI9GwDKisPODnogbfg1uXK6x/Djn jM9INmRWkNJ4plV4LPMwkD+bQ7okfRkuZxXdobL6zr5VXNSNWTvUh6R+4C+TYOhwrSQA Ybgb2+Ptlj6wCz+tAZ5hGzeQW3zuufJYjJDUBqvCKWJowJjVSR8b83YR0JauDI6SwDSG /O4p0iCI5De7krg9ZsjhUjDdU6bzXg927ltVB4pmK0WjRyozKzcB5UvCvSuOvk02JYzL Uzcn2oXNLEI3Qq3B8GnVIQNdjNvGhqhYr+3c40ERo+3F5Z2qs5UejvkeNmBrOlNfL21G JOgA== X-Gm-Message-State: AOJu0YzleTbnJ06oNmsSrYDcZTspbMHdExnxH9S889dv+ES8vJoBROBk aT6d2BnFom/WoAxiuhCianPAPv/SlF4stanqqJtEwY78bvNdZeSywXqoMEjOB1XzxjydKBIo1+J OFoqXaecK3p7QGvbY1HDsp5KaIVzs21NKM1v6kx4Opg== X-Gm-Gg: AeBDies3mHZU1B71Grzy/EiaHKGsKbw/4Ttm4MPszwHxDvQiuOPa0z1xvnRg0E8a1ag SsQKl73gzTsNU+s/I0CLWh8UBP6MmY+QXqbgXJfEKTUUKjxPlBCkZtyR6BxTVW3/EOoeTNYZSEK g44W2xML+JpuPEZVP05QPdzw4E3tj2aMvbWAqGn+OjgldaXLhJ/veEg5DzjxwfngDzomQKd0xx9 JfudP8bQbHfvdf99g1ALia7Uf2CK5Up7s5mpOCaZfyTDWv557rDly9iQUv0sMp3EmsPjDZKP49l MQKA7P4Egwl5zx5NDO5a X-Received: by 2002:a05:690e:588:b0:650:77fd:cf86 with SMTP id 956f58d0204a3-65198c01e52mr5887457d50.7.1776073988627; Mon, 13 Apr 2026 02:53:08 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: CharSyam Date: Mon, 13 Apr 2026 18:52:57 +0900 X-Gm-Features: AQROBzD1kAWn-XDoIe04MwbgmZw4jDMF98L6sq3hm3fEVndds3JvC2pyh5T0zz0 Message-ID: Subject: Re: [PATCH] Reduce pg_class scans in GRANT/REVOKE ON ALL TABLES IN SCHEMA To: Michael Paquier Cc: pgsql-hackers@lists.postgresql.org Content-Type: multipart/alternative; boundary="0000000000002fdf09064f547316" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000002fdf09064f547316 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable I ran a benchmark on the patch *Reduce pg_class scans in GRANT/REVOKE ON ALL TABLES IN SCHEMA* (collapses 5 per-relkind pg_class heap scans into 1 scan distributed into per-relkind buckets). Summary below.(It took much time to tests) ## Assumptions - Two builds of PostgreSQL 19devel from the same source tree (one patched, one at master tip), identical compile flags, separate --prefix. - Separate data directories, run sequentially on an otherwise idle host. - GUCs: shared_buffers=3D2GB, max_locks_per_transaction=3D100000, fsync=3Doff, synchronous_commit=3Doff, full_page_writes=3Doff, autovacuum=3Doff. - bench_s schema contains N empty tables (CREATE TABLE t_i()). - Measured operations: GRANT SELECT ON ALL TABLES IN SCHEMA bench_s TO bench_role REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA bench_s FROM bench_role - Best of 3 runs reported (seconds). - Two scenarios: A. Clean catalog =E2=80=94 VACUUM FULL pg_class; VACUUM FULL pg_att= ribute immediately before measurement. pg_class densely packed. B. Bloated catalog =E2=80=94 pre-bloat phase: GRANT+REVOKE on all N t= ables repeated C cycles, no VACUUM. Both patched and master operate on catalogs with identical relpages and n_dead_tup. ## Results =E2=80=94 Scenario A (Clean catalog) macOS (Apple Silicon), best of 3, seconds: ntables | GRANT patched | GRANT master | REVOKE patched | REVOKE master --------+---------------+--------------+----------------+-------------- 20,000 | 0.116 | 0.115 | 0.231 | 0.226 40,000 | 0.250 | 0.250 | 0.460 | 0.460 100,000 | 0.730 | 0.678 | 1.193 | 1.193 Honestly, there is no measurable performance difference in the clean state. Patched and master are statistically indistinguishable within run-to-run noise. This matches the design of the patch: when pg_class is densely packed, repeating a small seq scan five times is cheap, so collapsing it into one has nothing meaningful to save. The patch adds no overhead either =E2=80=94 worst case is a tie. ## Results =E2=80=94 Scenario B (Bloated catalog) ### Linux x86_64, C=3D20, best of 3, seconds ntables | dead_tup | GRANT patched | GRANT master | =CE=94 | R= EVOKE patched | REVOKE master | =CE=94 ----------+-----------+---------------+--------------+---------+-----------= -----+---------------+--------- 10,000 | 0 | 0.0924 | 0.0935 | =E2=88=921.2 % = | 0.1668 | 0.1696 | =E2=88=921.6 % 20,000 | 109,825 | 0.2027 | 0.2069 | =E2=88=922.0 % = | 0.3381 | 0.3533 | =E2=88=924.3 % 50,000 | 329,468 | 0.5555 | 0.5895 | =E2=88=925.8 % = | 0.8901 | 0.9371 | =E2=88=925.0 % 100,000 | 879,311 | 1.1732 | 1.1968 | =E2=88=922.0 % = | 1.8808 | 1.9555 | =E2=88=923.8 % 200,000 | 1,978,925 | 2.2188 | 2.3470 | =E2=88=925.5 % = | 3.7290 | 3.9064 | =E2=88=924.5 % 500,000 | 4,178,604 | 6.0260 | 6.6663 | =E2=88=929.6 % = | 9.8162 | 10.2169 | =E2=88=923.9 % 1,000,000 | 9,678,399 | 12.9241 | 14.7657 | =E2=88=9212.5 % = | 24.8893 | 28.7566 | =E2=88=9213.4 % ### macOS (Apple Silicon), C=3D20 (C=3D10 at 1M), best of 3, seconds ntables | dead_tup | GRANT patched | GRANT master | =CE=94 | RE= VOKE patched | REVOKE master | =CE=94 ----------+-----------+---------------+--------------+--------+------------= ----+---------------+-------- 20,000 | 299,960 | 0.168 | 0.163 | +3 % | 0.260 | 0.278 | =E2=88=926 % 40,000 | 519,601 | 0.307 | 0.307 | 0 % | 0.552 | 0.564 | =E2=88=922 % 100,000 | 959,268 | 0.784 | 0.934 | =E2=88=9216 % | 1.405 | 1.419 | ~0 % 200,000 | 2,058,886 | 1.787 | 1.878 | =E2=88=925 % | 2.745 | 2.849 | =E2=88=924 % 500,000 | 4,258,565 | 4.727 | 5.197 | =E2=88=929 % | 7.126 | 7.908 | =E2=88=9210 % 1,000,000 | 9,758,364 | 10.977 | 11.126 | =E2=88=921 % | 19.473 | 20.759 | =E2=88=926 % Negative =CE=94 =3D patched faster. Under catalog bloat the patch produce= s a consistent, reproducible improvement on both operating systems. Happy to share the bench scripts and raw logs on request. Thanks, charsyam 2026=EB=85=84 4=EC=9B=94 13=EC=9D=BC (=EC=9B=94) =EC=98=A4=EC=A0=84 9:43, M= ichael Paquier =EB=8B=98=EC=9D=B4 =EC=9E=91=EC=84=B1: > On Sun, Apr 12, 2026 at 04:22:24PM +0900, CharSyam wrote: > > Benchmark > > --------- > > This is a targeted micro-optimization, not a dramatic speedup. > > With 10,000 tables in a single schema (pg_class ~10,452 rows), > > running GRANT/REVOKE SELECT ON ALL TABLES IN SCHEMA in a loop > > (6 iterations, first dropped as warmup), I measured a consistent > > ~15% reduction in end-to-end time: > > > > baseline patched delta > > GRANT (avg) 88.2 ms 75.9 ms -14% > > REVOKE (avg) 134.9 ms 115.7 ms -14% > > I am pretty sure that there are users with millions of relations in a > single schema that could benefit from that. At least that would not > be surprising with partitioning these days, and foreign tables. What > kind of numbers do you get if you bump up the number of digits for > these tests. Let's say a comparison based on a few million relations > at least? > > The change you are proposing looks simple enough, quickly skimming > through the patch. There may be more optimizations doable here, I > have not looked at that, still I tend to like such micro-optimization > proposals as they provide a silent benefit. > -- > Michael > --0000000000002fdf09064f547316 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
=C2=A0 I ran a benchmark on the patch *Reduce pg_class sca= ns in GRANT/REVOKE
=C2=A0 ON ALL TABLES IN SCHEMA* (collapses 5 per-relk= ind pg_class heap scans
=C2=A0 into 1 scan distributed into per-relkind = buckets). Summary below.(It took much time to tests)


=C2=A0 ## A= ssumptions

=C2=A0 - Two builds of PostgreSQL 19devel from the same s= ource tree (one
=C2=A0 =C2=A0 patched, one at master tip), identical com= pile flags, separate
=C2=A0 =C2=A0 --prefix.
=C2=A0 - Separate data d= irectories, run sequentially on an otherwise idle
=C2=A0 =C2=A0 host.=C2=A0 - GUCs: shared_buffers=3D2GB, max_locks_per_transaction=3D100000,=C2=A0 =C2=A0 fsync=3Doff, synchronous_commit=3Doff, full_page_writes=3Do= ff,
=C2=A0 =C2=A0 autovacuum=3Doff.
=C2=A0 - bench_s schema contains = N empty tables (CREATE TABLE t_i()).
=C2=A0 - Measured operations:
= =C2=A0 =C2=A0 =C2=A0 GRANT =C2=A0SELECT ON ALL TABLES IN SCHEMA bench_s TO = =C2=A0 bench_role
=C2=A0 =C2=A0 =C2=A0 REVOKE ALL PRIVILEGES ON ALL TABL= ES IN SCHEMA bench_s FROM bench_role
=C2=A0 - Best of 3 runs reported (s= econds).
=C2=A0 - Two scenarios:
=C2=A0 =C2=A0 =C2=A0 A. Clean catalo= g =C2=A0 =E2=80=94 VACUUM FULL pg_class; VACUUM FULL pg_attribute
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0immediately before measurement. pg_class
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0densely packed.
=C2=A0 =C2=A0 =C2=A0 B. Bloated catalog =E2=80= =94 pre-bloat phase: GRANT+REVOKE on all N tables
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0repeated C cycles, no VACUUM. Both patched
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0an= d master operate on catalogs with identical
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0relpag= es and n_dead_tup.


=C2=A0 ## Results =E2=80=94 Scenario A (Clean= catalog)

=C2=A0 macOS (Apple Silicon), best of 3, seconds:

= =C2=A0 =C2=A0 ntables | GRANT patched | GRANT master | REVOKE patched | REV= OKE master
=C2=A0 =C2=A0 --------+---------------+--------------+-------= ---------+--------------
=C2=A0 =C2=A0 =C2=A020,000 | =C2=A0 =C2=A0 0.11= 6 =C2=A0 =C2=A0 | =C2=A0 =C2=A00.115 =C2=A0 =C2=A0 | =C2=A0 =C2=A0 0.231 = =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A00.226
=C2=A0 =C2=A0 =C2=A040,000 | = =C2=A0 =C2=A0 0.250 =C2=A0 =C2=A0 | =C2=A0 =C2=A00.250 =C2=A0 =C2=A0 | =C2= =A0 =C2=A0 0.460 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A00.460
=C2=A0 =C2=A0 = 100,000 | =C2=A0 =C2=A0 0.730 =C2=A0 =C2=A0 | =C2=A0 =C2=A00.678 =C2=A0 =C2= =A0 | =C2=A0 =C2=A0 1.193 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A01.193

= =C2=A0 Honestly, there is no measurable performance difference in the clean=
=C2=A0 state. Patched and master are statistically indistinguishable wi= thin
=C2=A0 run-to-run noise. This matches the design of the patch: when= pg_class
=C2=A0 is densely packed, repeating a small seq scan five time= s is cheap, so
=C2=A0 collapsing it into one has nothing meaningful to s= ave. The patch adds
=C2=A0 no overhead either =E2=80=94 worst case is a = tie.


=C2=A0 ## Results =E2=80=94 Scenario B (Bloated catalog)
=C2=A0 ### Linux x86_64, C=3D20, best of 3, seconds

=C2=A0 =C2= =A0 ntables =C2=A0 | dead_tup =C2=A0| GRANT patched | GRANT master | =C2=A0= =CE=94 =C2=A0 =C2=A0 | REVOKE patched | REVOKE master | =C2=A0 =CE=94
= =C2=A0 =C2=A0 ----------+-----------+---------------+--------------+-------= --+----------------+---------------+---------
=C2=A0 =C2=A0 =C2=A0 =C2= =A010,000 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 0 | =C2=A0 =C2=A00.0924 =C2=A0 =C2= =A0 | =C2=A0 =C2=A00.0935 =C2=A0 =C2=A0| =C2=A0=E2=88=921.2 % | =C2=A0 =C2= =A0 0.1668 =C2=A0 =C2=A0 | =C2=A0 =C2=A00.1696 =C2=A0 =C2=A0 | =C2=A0=E2=88= =921.6 %
=C2=A0 =C2=A0 =C2=A0 =C2=A020,000 | =C2=A0 109,825 | =C2=A0 =C2= =A00.2027 =C2=A0 =C2=A0 | =C2=A0 =C2=A00.2069 =C2=A0 =C2=A0| =C2=A0=E2=88= =922.0 % | =C2=A0 =C2=A0 0.3381 =C2=A0 =C2=A0 | =C2=A0 =C2=A00.3533 =C2=A0 = =C2=A0 | =C2=A0=E2=88=924.3 %
=C2=A0 =C2=A0 =C2=A0 =C2=A050,000 | =C2=A0= 329,468 | =C2=A0 =C2=A00.5555 =C2=A0 =C2=A0 | =C2=A0 =C2=A00.5895 =C2=A0 = =C2=A0| =C2=A0=E2=88=925.8 % | =C2=A0 =C2=A0 0.8901 =C2=A0 =C2=A0 | =C2=A0 = =C2=A00.9371 =C2=A0 =C2=A0 | =C2=A0=E2=88=925.0 %
=C2=A0 =C2=A0 =C2=A0 1= 00,000 | =C2=A0 879,311 | =C2=A0 =C2=A01.1732 =C2=A0 =C2=A0 | =C2=A0 =C2=A0= 1.1968 =C2=A0 =C2=A0| =C2=A0=E2=88=922.0 % | =C2=A0 =C2=A0 1.8808 =C2=A0 = =C2=A0 | =C2=A0 =C2=A01.9555 =C2=A0 =C2=A0 | =C2=A0=E2=88=923.8 %
=C2=A0= =C2=A0 =C2=A0 200,000 | 1,978,925 | =C2=A0 =C2=A02.2188 =C2=A0 =C2=A0 | = =C2=A0 =C2=A02.3470 =C2=A0 =C2=A0| =C2=A0=E2=88=925.5 % | =C2=A0 =C2=A0 3.7= 290 =C2=A0 =C2=A0 | =C2=A0 =C2=A03.9064 =C2=A0 =C2=A0 | =C2=A0=E2=88=924.5 = %
=C2=A0 =C2=A0 =C2=A0 500,000 | 4,178,604 | =C2=A0 =C2=A06.0260 =C2=A0 = =C2=A0 | =C2=A0 =C2=A06.6663 =C2=A0 =C2=A0| =C2=A0=E2=88=929.6 % | =C2=A0 = =C2=A0 9.8162 =C2=A0 =C2=A0 | =C2=A0 10.2169 =C2=A0 =C2=A0 | =C2=A0=E2=88= =923.9 %
=C2=A0 =C2=A0 1,000,000 | 9,678,399 | =C2=A0 12.9241 =C2=A0 =C2= =A0 | =C2=A0 14.7657 =C2=A0 =C2=A0| =E2=88=9212.5 % | =C2=A0 =C2=A024.8893 = =C2=A0 =C2=A0 | =C2=A0 28.7566 =C2=A0 =C2=A0 | =E2=88=9213.4 %

=C2= =A0 ### macOS (Apple Silicon), C=3D20 (C=3D10 at 1M), best of 3, seconds
=C2=A0 =C2=A0 ntables =C2=A0 | dead_tup =C2=A0| GRANT patched | GRANT = master | =C2=A0 =CE=94 =C2=A0 =C2=A0| REVOKE patched | REVOKE master | =C2= =A0 =CE=94
=C2=A0 =C2=A0 ----------+-----------+---------------+--------= ------+--------+----------------+---------------+--------
=C2=A0 =C2=A0 = =C2=A0 =C2=A020,000 | =C2=A0 299,960 | =C2=A0 =C2=A00.168 =C2=A0 =C2=A0 =C2= =A0| =C2=A0 =C2=A00.163 =C2=A0 =C2=A0 | =C2=A0+3 % =C2=A0| =C2=A0 =C2=A0 0.= 260 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A00.278 =C2=A0 =C2=A0 =C2=A0| =C2=A0= =E2=88=926 %
=C2=A0 =C2=A0 =C2=A0 =C2=A040,000 | =C2=A0 519,601 | =C2=A0= =C2=A00.307 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A00.307 =C2=A0 =C2=A0 | =C2= =A0 0 % =C2=A0| =C2=A0 =C2=A0 0.552 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A00.56= 4 =C2=A0 =C2=A0 =C2=A0| =C2=A0=E2=88=922 %
=C2=A0 =C2=A0 =C2=A0 100,000 = | =C2=A0 959,268 | =C2=A0 =C2=A00.784 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A00.= 934 =C2=A0 =C2=A0 | =E2=88=9216 % =C2=A0| =C2=A0 =C2=A0 1.405 =C2=A0 =C2=A0= =C2=A0| =C2=A0 =C2=A01.419 =C2=A0 =C2=A0 =C2=A0| =C2=A0~0 %
=C2=A0 =C2= =A0 =C2=A0 200,000 | 2,058,886 | =C2=A0 =C2=A01.787 =C2=A0 =C2=A0 =C2=A0| = =C2=A0 =C2=A01.878 =C2=A0 =C2=A0 | =C2=A0=E2=88=925 % =C2=A0| =C2=A0 =C2=A0= 2.745 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A02.849 =C2=A0 =C2=A0 =C2=A0| =C2= =A0=E2=88=924 %
=C2=A0 =C2=A0 =C2=A0 500,000 | 4,258,565 | =C2=A0 =C2=A0= 4.727 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A05.197 =C2=A0 =C2=A0 | =C2=A0=E2=88= =929 % =C2=A0| =C2=A0 =C2=A0 7.126 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A07.908= =C2=A0 =C2=A0 =C2=A0| =E2=88=9210 %
=C2=A0 =C2=A0 1,000,000 | 9,758,364= | =C2=A0 10.977 =C2=A0 =C2=A0 =C2=A0| =C2=A0 11.126 =C2=A0 =C2=A0 | =C2=A0= =E2=88=921 % =C2=A0| =C2=A0 =C2=A019.473 =C2=A0 =C2=A0 =C2=A0| =C2=A0 20.75= 9 =C2=A0 =C2=A0 =C2=A0| =C2=A0=E2=88=926 %

=C2=A0 Negative =CE=94 = =3D patched faster. Under catalog bloat the patch produces a
=C2=A0 cons= istent, reproducible improvement on both operating systems.


=C2= =A0 Happy to share the bench scripts and raw logs on request.

=C2=A0= Thanks,
=C2=A0 charsyam

2026=EB=85=84 4=EC=9B=94 1= 3=EC=9D=BC (=EC=9B=94) =EC=98=A4=EC=A0=84 9:43, Michael Paquier <michael@paquier.xyz>=EB=8B=98=EC=9D= =B4 =EC=9E=91=EC=84=B1:
On Sun, Apr 12, 2026 at 04:22:24PM +0900, CharSyam wrote:
>=C2=A0 =C2=A0Benchmark
>=C2=A0 =C2=A0---------
>=C2=A0 =C2=A0This is a targeted micro-optimization, not a dramatic spee= dup.
>=C2=A0 =C2=A0With 10,000 tables in a single schema (pg_class ~10,452 ro= ws),
>=C2=A0 =C2=A0running GRANT/REVOKE SELECT ON ALL TABLES IN SCHEMA in a l= oop
>=C2=A0 =C2=A0(6 iterations, first dropped as warmup), I measured a cons= istent
>=C2=A0 =C2=A0~15% reduction in end-to-end time:
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 baseline=C2=A0 =C2=A0 patched=C2=A0 =C2=A0 =C2=A0delta
>=C2=A0 =C2=A0 =C2=A0 =C2=A0GRANT=C2=A0 (avg)=C2=A0 =C2=A0 =C2=A088.2 ms= =C2=A0 =C2=A0 =C2=A075.9 ms=C2=A0 =C2=A0 -14%
>=C2=A0 =C2=A0 =C2=A0 =C2=A0REVOKE (avg)=C2=A0 =C2=A0 134.9 ms=C2=A0 =C2= =A0 115.7 ms=C2=A0 =C2=A0 -14%

I am pretty sure that there are users with millions of relations in a
single schema that could benefit from that.=C2=A0 At least that would not be surprising with partitioning these days, and foreign tables.=C2=A0 What<= br> kind of numbers do you get if you bump up the number of digits for
these tests.=C2=A0 Let's say a comparison based on a few million relati= ons
at least?

The change you are proposing looks simple enough, quickly skimming
through the patch.=C2=A0 There may be more optimizations doable here, I
have not looked at that, still I tend to like such micro-optimization
proposals as they provide a silent benefit.
--
Michael
--0000000000002fdf09064f547316--