prop/priv/repo/migrations/20260601202826_add_performance_indexes.exs
Graham McIntire 26be066f77
perf: fix critical performance issues
- NexradCache: replace :ets.tab2list() with foldl to avoid ~1.3 GB heap
  allocation on full cache (OOM risk)
- GridCache: replace :ets.select full-table copies with foldl in
  ets_latest_valid_time and ets_prune_keep_latest
- Weather.backfill_hrrr_batch: batch N individual UPDATEs into single
  VALUES-based SQL statement eliminating ~500 round-trips per batch
- Add 9 missing database indexes across 6 tables for hot-path queries
  (contacts, contact_edits, hrrr_profiles, hrrr_native_profiles,
  grid_tasks, rover_mission_paths, fixed_stations, beacons)
2026-06-01 15:29:29 -05:00

43 lines
1.7 KiB
Elixir

defmodule Microwaveprop.Repo.Migrations.AddPerformanceIndexes do
use Ecto.Migration
def change do
# contacts.flagged_invalid — admin flagged-contacts page filters + sorts
create index(:contacts, [:flagged_invalid, :inserted_at, :id])
# contact_edits.inserted_at — ORDER BY DESC on list and per-contact queries
create index(:contact_edits, [:inserted_at])
# contact_edits(contact_id, user_id, status) — pending-edit lookup
create index(:contact_edits, [:contact_id, :user_id, :status])
# hrrr_profiles.surface_refractivity IS NULL — backfill query scans for nulls
create index(:hrrr_profiles, [:surface_refractivity],
where: "surface_refractivity IS NULL",
name: "hrrr_profiles_surface_refractivity_null_idx"
)
# hrrr_native_profiles.bulk_richardson IS NULL — derive task scans for nulls
create index(:hrrr_native_profiles, [:bulk_richardson],
where: "bulk_richardson IS NULL AND level_count > 2",
name: "hrrr_native_profiles_bulk_richardson_null_idx"
)
# grid_tasks.claimed_at for status='running' — reclaim-stale query
create index(:grid_tasks, [:claimed_at],
where: "status = 'running'",
name: "grid_tasks_running_claimed_at_idx"
)
# rover_mission_paths composite — worker lookup on all 4 columns
create index(:rover_mission_paths, [:mission_id, :rover_location_id, :station_id, :band_mhz],
name: "rover_mission_paths_lookup_idx"
)
# fixed_stations(user_id, position, inserted_at) — WHERE + ORDER BY
create index(:fixed_stations, [:user_id, :position, :inserted_at])
# beacons(user_id, inserted_at) — WHERE + ORDER BY
create index(:beacons, [:user_id, :inserted_at])
end
end