rls-performancelisted
Install: claude install-skill YuDefine/nuxt-supabase-starter
<!-- 🔒 LOCKED — managed by clade · auto-generated by sync-to-agents; edit source in .claude/ then re-run sync -->
# RLS Performance Playbook
大型專案常累積大量 RLS policy 與 SECURITY DEFINER function,加上 self-hosted LXC 的 connection pool 限制,任何 N+1 或 full scan 都會被放大。本 skill 是遇到效能問題時的操作手冊。
決策原則(「MUST 做 / NEVER 做」)仍在 `.claude/rules/{database,database-design}.md`,本檔提供**實際診斷與優化工具**。
## 何時開啟本 skill
- 新增涉及 policy join 的表
- 修改既有 RLS policy 的 WHERE 條件
- 新增 server API endpoint 含 pagination / filter
- 遇到 `PGRST003`(504 timeout)或 pool 耗盡
- 使用者抱怨特定頁面 / endpoint 變慢
- 需要稽核 production 效能或清理無用 index
- 排查 LXC 連線問題 / Tunnel 斷線
**核心原則**:policy 改動前先量,改動後驗證,不要憑感覺優化。
## EXPLAIN ANALYZE — 正確的 RLS 測量方式
**關鍵陷阱**:superuser 跑 EXPLAIN 會 **bypass RLS**,測出來的 plan 跟 production 完全不同。**一定要** `set local role` 模擬目標角色。
```sql
-- 1. 模擬目標 role(不是 postgres superuser!)
set local role authenticated;
set local request.jwt.claims to '{"sub": "<user_uuid>", "role": "authenticated"}';
-- 2. 跑實際 query
explain (analyze, buffers, verbose, format text)
select ... from <schema>.<table> where ...;
-- 3. 還原
reset role;
```
### 讀 plan 重點
| Plan 片段 | 意義 | 處理 |
| ---------------------------------- | ---------------------------- | -------------------------------------------------- |
| `Seq Scan on xxx` | 全表掃描 | 檢查 WHERE 欄位是否有 index |
| `Rows Removed by Filter: > 1000` | Inde