RLS isn't slow, this policy is. Two fixes:
- Wrap the function in a subselect so Postgres evaluates it once per query instead of once per row:
drop policy "own events" on events;
create policy "own events" on events for select to authenticated
using ((select auth.uid()) = user_id);- Index the column the policy filters on:
create index on events (user_id);Also adding to authenticated means the policy isn't even evaluated for anonymous requests. And keep the .eq('user_id', ...) in the client: the planner can use it directly, the policy is a safety net.
To see the real plan as your user, run in the SQL editor:
set local role authenticated;
set local request.jwt.claims = '{"sub":"<user-uuid>"}';
explain analyze select * from events;