Files
goodgo-platform/prisma
Ho Ngoc Hai 915b9fd806 feat(db): add FTS GIN + savedSearch partial indexes (GOO-118)
Convert the query-optimization recommendations from GOO-57 audit plan
document into concrete Prisma migration changes. Neither index can be
expressed in Prisma schema (expression index / partial WHERE), so both
land as raw SQL in a single migration.

Indexes added:

- idx_property_fts — GIN expression index on Property matching the
  search-query-builder FTS_COLUMNS expression exactly:
    to_tsvector('simple', coalesce(title,'') || ' ' || coalesce(description,'')
                 || ' ' || coalesce(address,'') || ' ' || coalesce(district,'')
                 || ' ' || coalesce(city,''))
  Addresses GOO-57 M-3 (missing GIN index for FTS).

- idx_savedsearch_alert_enabled — partial btree on SavedSearch(createdAt)
  WHERE alertEnabled = true, used by the residential alert listeners and
  the saved-search cron (supports GOO-57 H-1 / H-2 follow-up work —
  eliminating the seq scan is the prerequisite for cursor batching).

Benchmarks (local PG16, synthetic data):

Property FTS with a selective term (50k rows, ~10 matching):
  with idx_property_fts:    3.97 ms (Bitmap Heap Scan, 338 buffers)
  without index:          242.56 ms (Parallel Seq Scan, 1784 buffers)
  → ~61x faster.

SavedSearch alert scan (100k rows, 5% alertEnabled, LIMIT 500 ORDER BY
createdAt DESC):
  with idx_savedsearch_alert_enabled:  0.48 ms (Index Scan Backward)
  without index:                       6.05 ms (Seq Scan + top-N sort)
  → ~12x faster, seq scan eliminated.

Hook-up verified: pnpm db:generate clean; raw migration applies via
prisma migrate deploy; post-migration \d confirms both indexes are
present with the expected definitions.

Refs: GOO-118, GOO-57
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-23 21:25:09 +07:00
..