← back to Stayclaim

db/migrations/024_perf_indexes.sql

41 lines

-- Performance indexes flagged by perf-engineer in 2026-05-05 review.
-- All idempotent — IF NOT EXISTS guards. CONCURRENTLY would be ideal at
-- LA scale but isn't allowed inside a transaction; psql -f wraps each
-- file in a single tx, so we use plain CREATE INDEX. Acceptable since
-- pastdoor's listing/place_event tables are <1M rows.

-- listing.source — partial index for the public-listings filter on
-- FlagshipHome.getFeaturedHouses (`source = 'wikipedia_house'`) and
-- houses/page (`source IN ('wikipedia_house','la_hcm')`).
CREATE INDEX IF NOT EXISTS idx_listing_source
  ON listing (source) WHERE is_public = true;

-- listing.ingested_at DESC — used as ORDER BY in searchListings,
-- getNearbyListings, /api/search. With LIMIT N a btree-DESC index
-- means limit-via-index instead of full sort.
CREATE INDEX IF NOT EXISTS idx_listing_ingested_at
  ON listing (ingested_at DESC) WHERE is_public = true;

-- listing.claimed_at DESC — ClaimHome.getRecentClaims orders by
-- claimed_at. Existing idx_listing_claimed is on claimed_by.
CREATE INDEX IF NOT EXISTS idx_listing_claimed_at
  ON listing (claimed_at DESC) WHERE claimed_by IS NOT NULL;

-- place_event composite (kind, valid_from DESC) — getRecentPermits
-- filters on kind+public_visible+ORDER BY valid_from DESC. Today the
-- planner picks one of the two single-column indexes; the composite
-- supports both.
CREATE INDEX IF NOT EXISTS idx_place_event_kind_validfrom
  ON place_event (kind, valid_from DESC) WHERE public_visible;

-- pg_trgm on listing.title and entity.display_name for ILIKE %x%
-- supplied by /api/search and houses/page. Existing idx_listing_search_doc
-- is tsvector-only; bare ILIKE doesn't use it.
CREATE EXTENSION IF NOT EXISTS pg_trgm;

CREATE INDEX IF NOT EXISTS idx_listing_title_trgm
  ON listing USING gin (title gin_trgm_ops);

CREATE INDEX IF NOT EXISTS idx_entity_name_trgm
  ON entity USING gin (display_name gin_trgm_ops);