perf(db): physflat-covering индекс v2 с price_per_m2_rub в INCLUDE (#2177 follow-up) #2243

Merged
bot-backend merged 1 commit from feat/physflat-idx-include into main 2026-07-03 00:49:08 +00:00
Collaborator

Summary

  • Follow-up ревью #2240: supply-only запрос best-layouts проецирует price_per_m2_rub, которого нет в INCLUDE objective_lots_physflat_covering_idx → планер уходит в heap scan + external-merge sort (7 МБ диск): worst-case ~500 мс; с колонкой в INCLUDE — Index Only Scan, ~54 мс (EXPLAIN-доказано на двух тяжелейших проектах).
  • Миграция 183_...: CREATE INDEX IF NOT EXISTS ..._v2_idx (тот же ключ/partial-WHERE, INCLUDE + price_per_m2_rub) → DROP старого → ANALYZE. v2-имя, а не DROP+CREATE того же — иначе IF NOT EXISTS под старым именем стал бы no-op и молча пропустил пересборку. Без CONCURRENTLY — политика репо (deploy.yml гоняет .sql в BEGIN/COMMIT, зафиксировано в 168-й); plain CREATE под кратким SHARE-lock, деплой вне окна objective-scrape (вторник 04:00).
  • Backend-код не меняется — индекс прозрачен для _SUPPLY_ONLY_LOTS_SQL.

Test plan

  • Паттерн 1-в-1 со 176-й (та же таблица, тот же способ), все 16 колонок сверены с 68_schema
  • post-deploy verify (правило: deploy success ≠ применилось): \di+ objective_lots_physflat_covering* — v2 есть, старого нет; EXPLAIN supply-only на тяжёлом проекте → Index Only Scan

Refs #2177

## Summary - Follow-up ревью #2240: supply-only запрос best-layouts проецирует `price_per_m2_rub`, которого нет в INCLUDE `objective_lots_physflat_covering_idx` → планер уходит в heap scan + external-merge sort (7 МБ диск): worst-case **~500 мс**; с колонкой в INCLUDE — Index Only Scan, **~54 мс** (EXPLAIN-доказано на двух тяжелейших проектах). - Миграция `183_...`: `CREATE INDEX IF NOT EXISTS ..._v2_idx` (тот же ключ/partial-WHERE, INCLUDE + price_per_m2_rub) → `DROP` старого → `ANALYZE`. **v2-имя, а не DROP+CREATE того же** — иначе `IF NOT EXISTS` под старым именем стал бы no-op и молча пропустил пересборку. Без CONCURRENTLY — политика репо (deploy.yml гоняет .sql в `BEGIN/COMMIT`, зафиксировано в 168-й); plain CREATE под кратким SHARE-lock, деплой вне окна objective-scrape (вторник 04:00). - Backend-код не меняется — индекс прозрачен для `_SUPPLY_ONLY_LOTS_SQL`. ## Test plan - [x] Паттерн 1-в-1 со 176-й (та же таблица, тот же способ), все 16 колонок сверены с 68_schema - [ ] post-deploy verify (правило: deploy success ≠ применилось): `\di+ objective_lots_physflat_covering*` — v2 есть, старого нет; EXPLAIN supply-only на тяжёлом проекте → Index Only Scan Refs #2177
bot-backend added 1 commit 2026-07-03 00:34:09 +00:00
data/sql/183: physflat covering index v2 with price_per_m2_rub (#2240)
All checks were successful
CI / changes (pull_request) Successful in 9s
CI Trade-In / changes (pull_request) Successful in 10s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 2m7s
CI / backend-tests (pull_request) Successful in 14m20s
a83dd582a6
Follow-up review #2240: best_layouts._SUPPLY_ONLY_LOTS_SQL projects
price_per_m2_rub after DISTINCT ON (physflat), but the 176-й covering
index does not carry it in INCLUDE, so Index-Only Scan is impossible and
heavy projects fall back to heap scan + external-merge Sort (~7 MB temp,
~500 ms).

Rebuild the covering index as v2 with price_per_m2_rub added to INCLUDE.
Same key + partial-WHERE as 176-й, so all prior consumers are unchanged;
supply-only now gets Index Only Scan (~54 ms, prod EXPLAIN on the two
heaviest projects).

CREATE new v2 name -> DROP old (mirrors 176-й ordering; never a window
without a covering index under DISTINCT ON). Plain CREATE INDEX in
BEGIN/COMMIT, NOT CONCURRENTLY: deploy.yml pipes each .sql whole through
psql and the file self-wraps in BEGIN/COMMIT, where CONCURRENTLY is
forbidden (same policy as 168-й/176-й). Deploy outside the weekly
objective-scrape window (~252 MB build under brief SHARE-lock on
objective_lots, ~1.9M rows). ANALYZE at end of tx.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bot-backend merged commit 5888b0b9d3 into main 2026-07-03 00:49:08 +00:00
bot-backend deleted branch feat/physflat-idx-include 2026-07-03 00:49:08 +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#2243
No description provided.