[ PROMPT_NODE_25148 ]
security-rls-performance
[ SKILL_DOCUMENTATION ]
## 优化 RLS 策略以提升性能
编写不当的 RLS 策略会导致严重的性能问题。请策略性地使用子查询和索引。
**错误(每行调用一次函数):**
sql
create policy orders_policy on orders
using (auth.uid() = user_id); -- auth.uid() 对每一行调用!
-- 如果有 100 万行数据,auth.uid() 将被调用 100 万次
**正确(将函数包装在 SELECT 中):**
sql
create policy orders_policy on orders
using ((select auth.uid()) = user_id); -- 只调用一次,并缓存结果
-- 在大表上速度提升 100 倍以上
对复杂检查使用安全定义者 (security definer) 函数:
sql
-- 创建辅助函数(以定义者身份运行,绕过 RLS)
create or replace function is_team_member(team_id bigint)
returns boolean
language sql
security definer
set search_path = ''
as $$
select exists (
select 1 from public.team_members
where team_id = $1 and user_id = (select auth.uid())
);
$$;
-- 在策略中使用(索引查找,而非逐行检查)
create policy team_orders_policy on orders
using ((select is_team_member(team_id)));
始终为 RLS 策略中使用的列添加索引:
sql
create index orders_user_id_idx on orders (user_id);
参考:[RLS 性能](https://supabase.com/docs/guides/database/postgres/row-level-security#rls-performance-recommendations)