perf(tradein): GIST index on (geom::geography) for estimator radius filter (#1189) #1924

Merged
bot-backend merged 2 commits from perf/1189-listings-geom-geography-gist into main 2026-06-26 17:12:50 +00:00
Collaborator

#1189 — EXPLAIN-решение об индексе (measured, not blind)

Estimator analog query (Tier W/H/S radius) uses ST_DWithin(geom::geography, point, radius), but listings_geom_idx is gist(geom) (geometry). The geography cast prevents the planner from using it spatially → ST_DWithin falls to a Filter, and the geom index runs only geom IS NOT NULL (scans 54.5k rows).

Prod EXPLAIN (2026-06-26, ЕКБ point r=1500, 2-room 45-65m²):

  • before: BitmapAnd(geom IS NOT NULL=54531) + Filter ST_DWithin180ms, read 3961 buffers.
  • after (this index): Index Scan ... (geom::geography) && _st_expand(point,1500)~38ms (~4.7×), ~5k rows touched.

Measured by dry-run on real prod (BEGIN; CREATE INDEX; EXPLAIN ANALYZE; ROLLBACK) — not blind (per #1189's "не создавать индекс вслепую").

Migration 134

CREATE INDEX IF NOT EXISTS listings_geom_geog_idx ON listings USING gist ((geom::geography)).

  • Additive, idempotent (IF NOT EXISTS), non-destructive — no data touched.
  • No code change: estimator already casts geom::geography, so ST_DWithin starts using the index as Index Cond automatically.
  • listings_geom_idx (gist(geom)) kept for geometry-space paths.
  • Build over ~54.5k non-null geom rows is fast (~1-2s, brief ACCESS EXCLUSIVE during build). Non-CONCURRENT (migration runner is transactional).

Refs #1189

## #1189 — EXPLAIN-решение об индексе (measured, not blind) Estimator analog query (Tier W/H/S radius) uses `ST_DWithin(geom::geography, point, radius)`, but `listings_geom_idx` is `gist(geom)` (geometry). The geography cast prevents the planner from using it spatially → `ST_DWithin` falls to a **Filter**, and the geom index runs only `geom IS NOT NULL` (scans **54.5k rows**). **Prod EXPLAIN (2026-06-26, ЕКБ point r=1500, 2-room 45-65m²):** - **before:** `BitmapAnd(geom IS NOT NULL=54531) + Filter ST_DWithin` → **180ms**, read 3961 buffers. - **after** (this index): `Index Scan ... (geom::geography) && _st_expand(point,1500)` → **~38ms (~4.7×)**, ~5k rows touched. Measured by **dry-run on real prod** (`BEGIN; CREATE INDEX; EXPLAIN ANALYZE; ROLLBACK`) — not blind (per #1189's "не создавать индекс вслепую"). ## Migration 134 `CREATE INDEX IF NOT EXISTS listings_geom_geog_idx ON listings USING gist ((geom::geography))`. - Additive, idempotent (`IF NOT EXISTS`), non-destructive — no data touched. - No code change: estimator already casts `geom::geography`, so `ST_DWithin` starts using the index as Index Cond automatically. - `listings_geom_idx` (gist(geom)) kept for geometry-space paths. - Build over ~54.5k non-null geom rows is fast (~1-2s, brief ACCESS EXCLUSIVE during build). Non-CONCURRENT (migration runner is transactional). Refs #1189
bot-backend added 1 commit 2026-06-26 17:09:28 +00:00
perf(tradein): GIST index on (geom::geography) for estimator radius filter (#1189)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
57456b5d10
Estimator analog query casts geom::geography for ST_DWithin, but listings_geom_idx
is gist(geom) → spatial predicate fell to Filter, geom index used only for
geom IS NOT NULL (54.5k-row scan, 180ms). Add gist((geom::geography)) expression
index → ST_DWithin uses it as Index Cond. Prod dry-run (BEGIN/CREATE/EXPLAIN/ROLLBACK):
180ms → 38ms (~4.7x). Additive, idempotent (IF NOT EXISTS), non-destructive.
Light1YT added 1 commit 2026-06-26 17:12:10 +00:00
review: wrap migration 134 in BEGIN/COMMIT (runner not --single-transaction)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
cf165bfd66
bot-backend merged commit d89210200b into main 2026-06-26 17:12:50 +00:00
bot-backend deleted branch perf/1189-listings-geom-geography-gist 2026-06-26 17:12:50 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1924
No description provided.