-- #93 (PR #95): indexes for on-demand cadastre fetch lookups. -- -- Context: -- `find_active_on_demand_job` и `find_recent_completed_job` в -- `app/services/site_finder/cadastre_fetch.py` фильтруют -- `nspd_geo_targets` по cad_num + `nspd_geo_jobs` по source_kind+status. -- Existing UNIQUE(job_id, cad_num, thematic_id) на targets не помогает -- при WHERE cad_num=:c — нужен secondary index. -- -- Не блокер при текущем размере таблицы (~10K targets), но критично при -- ускорении on-demand traffic (per #93 trigger любым посетителем -- /site-finder). -- -- Apply: idempotent, CREATE INDEX IF NOT EXISTS — safe to run multiple -- times. CONCURRENTLY не используется чтобы коммит был атомарным; на -- prod размере index build занимает <1s. BEGIN; -- Targets — поиск активных on-demand job'ов для конкретного cad CREATE INDEX IF NOT EXISTS nspd_geo_targets_cad_num_idx ON nspd_geo_targets(cad_num); -- Jobs — фильтр source_kind='auto_on_demand' + status IN (queued,running) CREATE INDEX IF NOT EXISTS nspd_geo_jobs_source_status_idx ON nspd_geo_jobs(source_kind, status); COMMIT; COMMENT ON INDEX nspd_geo_targets_cad_num_idx IS 'on-demand cadastre fetch lookups (#93). Used by find_active_on_demand_job ' 'и find_recent_completed_job в cadastre_fetch service.'; COMMENT ON INDEX nspd_geo_jobs_source_status_idx IS 'Filter source_kind=auto_on_demand + status (#93). Composite чтобы ' 'покрыть оба predicate сразу.';