perf(objective_lots): drop 3 dead indexes (status/rooms_area/bank) — write-amp (#1953) #2056

Merged
bot-backend merged 1 commit from perf/drop-dead-objective-lots-indexes-1953 into main 2026-06-28 14:39:06 +00:00
Collaborator

Perf-хант #4. Дроп 3 verified-мёртвых индексов на hot-UPSERT таблице objective_lots (миграция 177).

Прод-verify (35d uptime, без reset): status_idx idx_scan=8 (предикат LOWER(COALESCE(status,..))=.. не-sargable→seq-scan), rooms_area_idx=7 (rooms_int/area_pd только в SELECT/CASE, не в WHERE), bank_idx=2 (bank_name только в has_mortgage-проекции). EXPLAIN подтвердил — планировщик их не выбирает. Ни одного hot/periodic консьюмера (grep).

trgm_idx (236МБ) НЕ тронут — ETL-консьюмер (objective_backfill similarity()), отдельный тикет.

~97МБ диск + write-amp на каждом upsert. Reversible (68_schema_objective.sql:250-256). DROP IF EXISTS, BEGIN/COMMIT, идемпотентно, dry-run на проде чисто. Refs #1953.

Perf-хант #4. Дроп 3 verified-мёртвых индексов на hot-UPSERT таблице objective_lots (миграция 177). Прод-verify (35d uptime, без reset): status_idx idx_scan=8 (предикат LOWER(COALESCE(status,..))=.. не-sargable→seq-scan), rooms_area_idx=7 (rooms_int/area_pd только в SELECT/CASE, не в WHERE), bank_idx=2 (bank_name только в has_mortgage-проекции). EXPLAIN подтвердил — планировщик их не выбирает. Ни одного hot/periodic консьюмера (grep). trgm_idx (236МБ) НЕ тронут — ETL-консьюмер (objective_backfill similarity()), отдельный тикет. ~97МБ диск + write-amp на каждом upsert. Reversible (68_schema_objective.sql:250-256). DROP IF EXISTS, BEGIN/COMMIT, идемпотентно, dry-run на проде чисто. Refs #1953.
bot-backend added 1 commit 2026-06-28 14:15:08 +00:00
perf(objective_lots): drop 3 dead indexes to cut UPSERT write-amp (#1953)
All checks were successful
CI / changes (pull_request) Successful in 8s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m17s
CI / backend-tests (pull_request) Successful in 14m47s
800e68af58
perf-hunt finding #4: objective_lots is a hot UPSERT table (1.76M ins /
1.39M upd over 35d) — each write maintains every index. These three have
near-zero lifetime idx_scan AND no sargable consumer anywhere in the
backend/SQL, so they are pure write-amplification:

  - objective_lots_status_idx   (idx_scan=8,  19 MB) — consumers use
    LOWER(COALESCE(status,''))='продан', not sargable on plain B-tree
  - objective_lots_rooms_area_idx (idx_scan=7, 78 MB) — rooms_int/area_pd
    only in SELECT projections + CASE-bucket, never a WHERE/ORDER filter
  - objective_lots_bank_idx     (idx_scan=2,  8 KB) — bank_name only in an
    IS NOT NULL projection; WHERE bank_name= is a different table

Verified on prod: EXPLAIN of each real query shape → Seq Scan (index not
chosen even when present). Frees ~97 MB + per-write WAL/maintenance.
Idempotent (DROP INDEX IF EXISTS), BEGIN/COMMIT, dry-run clean.
Rollback: recreate from data/sql/68_schema_objective.sql:250-256.

NOT touched: project_name_trgm_idx (236 MB) — has an ETL consumer
(objective_backfill.py similarity()); needs separate ETL-cadence check.
bot-backend merged commit c97dd57e1c into main 2026-06-28 14:39:06 +00:00
bot-backend deleted branch perf/drop-dead-objective-lots-indexes-1953 2026-06-28 14:39:06 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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#2056
No description provided.