-- CreateIndex —— 新筛选维度「上次时间」(visit_recency.bucket)的偏索引
--
-- 与 20260728020000 那 14 条同一套路数、同一理由,不再重复长篇:
--   Prisma 把画像筛选编译成 `key = 'visit_recency' AND (data #> '{bucket}') = '"0_3m"'`,
--   没有这条索引,planner 只能按 key 捞出**全部** visit_recency 行再回堆过滤 jsonb。
--   2026-07-29 生产实测过后果:禁忌维度 190,210 行里只中 2,156 行,读 1.3GB 堆、单次筛人 20+ 秒。
--
-- ⚠️ **加筛选维度必须同时加索引** —— 这是 persona-tag-filters.ts 顶部写死的纪律,
--   本条就是「上次时间」维度的那一条。漏了它,新维度一上线就是 20 秒起步。
--
-- 形态:标量维度(equals)→ btree (表达式, persona_id)。
--   第二列 persona_id 不是排序用,是让内层 EXISTS 走 **index-only scan**:
--   它只 SELECT persona_id,索引自带就不用回堆(详见 20260728020000 的实测数据)。
--
-- 【为什么不是 CONCURRENTLY】本文件只有 1 条语句,本可以 CONCURRENTLY;但 visit_recency
--   是**新特征**,建索引时表里一行都没有(要等下一轮画像重算才写入),普通 CREATE INDEX
--   瞬间完成、锁不到任何东西。等重算铺开后再想加别的维度索引,才需要 CONCURRENTLY + 手工先建。
CREATE INDEX IF NOT EXISTS "persona_features_visit_recency_bucket_idx"
  ON "persona_features" (((data #> '{bucket}'::text[])), "persona_id") WHERE "key" = 'visit_recency';
