I wrote: > I poked into this a bit. It seems the problem is that as of v16, we > try to search for the "best" role membership path from the current > user to the target role, and that's done in a very brute-force way, > as a side effect of computing the set of *all* role memberships the > current role has.
Actually, roles_is_member_of sucks before v16 too; the new thing is only that it's being invoked during GRANT ROLE. Using the roles created by the given test case, I see in v15: $ psql psql (15.6) Type "help" for help. regression=# drop table at; DROP TABLE regression=# set role a_0010308; SET regression=> create table at(f1 int); CREATE TABLE regression=> \timing Timing is on. regression=> set role acc; SET Time: 0.493 ms regression=> insert into at values(1); INSERT 0 1 Time: 3565.029 ms (00:03.565) regression=> insert into at values(1); INSERT 0 1 Time: 2.308 ms So it takes ~3.5s to populate the roles_is_member_of cache for "acc" given this membership set. This is actually considerably worse than in v16 or HEAD, where the same test takes about 1.6s for me. Apparently the OP has designed their use-case so that they dodge these implementation problems in v15 and earlier, but that's a far cry from saying that there were no problems with lots-o-roles before v16. regards, tom lane