towerops/priv/repo/migrations/20260212155105_add_performance_indexes.exs
Graham McIntire aa1bac0d46
perf: batch inserts, selective LiveView reloading, and database indexes for scale
Replace individual Repo.insert() with Repo.insert_all() for sensor readings,
interface stats, processor readings, and storage readings in agent channel and
device poller worker. Add partial/composite database indexes for common query
patterns. Dashboard now uses GROUP BY aggregation instead of loading all devices.
DeviceLive.Show only reloads data for the active tab on PubSub events.
DeviceLive.Index debounces status changes and skips quota queries on updates.
Agent polling preloads filtered to monitored sensors/interfaces only.
2026-02-12 10:16:10 -06:00

39 lines
1.3 KiB
Elixir

defmodule Towerops.Repo.Migrations.AddPerformanceIndexes do
use Ecto.Migration
@disable_ddl_transaction true
@disable_migration_lock true
def change do
# Partial index for monitored sensors (WHERE monitored = true)
# Used by Snmp.list_monitored_sensors/1
create index(:snmp_sensors, [:monitored],
where: "monitored = true",
name: :snmp_sensors_monitored_true_idx,
concurrently: true
)
# Partial index for monitored interfaces (WHERE monitored = true)
# Used by Snmp.list_monitored_interfaces/1
create index(:snmp_interfaces, [:monitored],
where: "monitored = true",
name: :snmp_interfaces_monitored_true_idx,
concurrently: true
)
# Composite index for devices filtered by org + status
# Used by Devices.list_organization_devices/2 with status filter
create index(:devices, [:organization_id, :status],
name: :devices_organization_id_status_idx,
concurrently: true
)
# Partial index for active (unresolved) alerts
# Used by Alerts.list_organization_active_alerts/1
create index(:alerts, [:resolved_at],
where: "resolved_at IS NULL",
name: :alerts_active_idx,
concurrently: true
)
end
end