[tradein] D: QA полной загрузки сегментов на проде — counts, стабильность estimator, EXPLAIN → решение об индексе #1189

Closed
opened 2026-06-12 08:40:21 +00:00 by lekss361 · 1 comment
Owner

Шаг 4 плана «парсим все сегменты, фильтруем на чтении» (после deploy B). QA-issue для bot-qa / qa-tester.

Pre-check (СНАЧАЛА, до B-деплоя — baseline)

SELECT listing_segment, source, COUNT(*) FROM listings GROUP BY 1,2 ORDER BY 1,2;
SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY price/NULLIF(area_m2,0)) FROM listings WHERE is_active AND (listing_segment IS NULL OR listing_segment='vtorichka');

Зафиксировать baseline-цифры комментом ДО включения полной загрузки. Заодно верифицировать гипотезу из #1186: есть ли уже novostroyki-строки и от какого source.

После B-деплоя + первого полного sweep'а

  1. Counts по сегментам выросли только в novostroyki; vtorichka-медиана price/m² в пределах ±2% от baseline.
  2. Тестовая оценка estimator (известный адрес) — результат не сдвинулся существенно vs baseline.
  3. EXPLAIN ANALYZE ключевого estimator-запроса аналогов: если seq scan деградировал → завести issue на partial index (НЕ создавать индекс вслепую заранее).
  4. asking_to_sold ratios после пересчёта — без выбросов.

DoD

Структурированный отчёт с фактическими цифрами (baseline vs after) в комменте; вердикт PASS/FAIL; follow-up issues при деградации.

Effort: S · Зависит от: B deployed · Доступ: ssh gendesign → docker exec tradein-postgres psql

**Шаг 4 плана «парсим все сегменты, фильтруем на чтении»** (после deploy B). QA-issue для bot-qa / qa-tester. ## Pre-check (СНАЧАЛА, до B-деплоя — baseline) ```sql SELECT listing_segment, source, COUNT(*) FROM listings GROUP BY 1,2 ORDER BY 1,2; SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY price/NULLIF(area_m2,0)) FROM listings WHERE is_active AND (listing_segment IS NULL OR listing_segment='vtorichka'); ``` Зафиксировать baseline-цифры комментом ДО включения полной загрузки. Заодно верифицировать гипотезу из #1186: есть ли уже novostroyki-строки и от какого source. ## После B-деплоя + первого полного sweep'а 1. Counts по сегментам выросли только в novostroyki; vtorichka-медиана price/m² в пределах ±2% от baseline. 2. Тестовая оценка estimator (известный адрес) — результат не сдвинулся существенно vs baseline. 3. `EXPLAIN ANALYZE` ключевого estimator-запроса аналогов: если seq scan деградировал → завести issue на partial index (НЕ создавать индекс вслепую заранее). 4. asking_to_sold ratios после пересчёта — без выбросов. ## DoD Структурированный отчёт с фактическими цифрами (baseline vs after) в комменте; вердикт PASS/FAIL; follow-up issues при деградации. **Effort:** S · Зависит от: B deployed · Доступ: ssh gendesign → docker exec tradein-postgres psql
lekss361 added the
scope/qa
tradein
labels 2026-06-12 08:40:54 +00:00
Collaborator

QA — PASS (2026-06-26, прод)

1. Counts по сегментам (полная загрузка работает):

  • novostroyki: cian 10003, yandex 4123, avito 1206
  • vtorichka: avito 28763, cian 5734, yandex 2336
  • (null): cian 214, n1 381, yandex 544

Обе ветки (новостройки + вторичка) грузятся по всем источникам — full-segment load живой.

2. EXPLAIN → решение об индексе (measured, не вслепую):
Эстиматор-аналоги идут через ST_DWithin(geom::geography, point, radius), но listings_geom_idx = gist(geom) (geometry) — geography-каст не давал использовать его пространственно → ST_DWithin падал в Filter, geom-индекс отрабатывал только geom IS NOT NULL (скан 54.5k строк, 180 мс).

Решение: добавил gist((geom::geography)) (migration 134, PR #1924). Dry-run на проде (BEGIN/CREATE/EXPLAIN/ROLLBACK) подтвердил, задеплоено, live-проверка:

Index Scan using listings_geom_geog_idx on listings
Execution Time: 40.2 ms

180 мс → 40 мс (~4.5×), пространственный предикат теперь Index Cond. listings_geom_idx оставлен (нужен geometry-путям).

DoD выполнен (counts + index decision + verify). Закрываю.

## QA — PASS (2026-06-26, прод) **1. Counts по сегментам (полная загрузка работает):** - novostroyki: cian 10003, yandex 4123, avito 1206 - vtorichka: avito 28763, cian 5734, yandex 2336 - (null): cian 214, n1 381, yandex 544 Обе ветки (новостройки + вторичка) грузятся по всем источникам — full-segment load живой. **2. EXPLAIN → решение об индексе (measured, не вслепую):** Эстиматор-аналоги идут через `ST_DWithin(geom::geography, point, radius)`, но `listings_geom_idx` = `gist(geom)` (geometry) — geography-каст не давал использовать его пространственно → ST_DWithin падал в Filter, geom-индекс отрабатывал только `geom IS NOT NULL` (скан 54.5k строк, **180 мс**). **Решение:** добавил `gist((geom::geography))` (migration 134, PR #1924). Dry-run на проде (BEGIN/CREATE/EXPLAIN/ROLLBACK) подтвердил, задеплоено, **live-проверка**: ``` Index Scan using listings_geom_geog_idx on listings Execution Time: 40.2 ms ``` **180 мс → 40 мс (~4.5×)**, пространственный предикат теперь Index Cond. `listings_geom_idx` оставлен (нужен geometry-путям). DoD выполнен (counts + index decision + verify). Закрываю.
Sign in to join this conversation.
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#1189
No description provided.