fix: add missing foreign key indexes for performance and referential integrity (#167)
Missing indexes detected on 7 foreign key columns: - on_call_overrides.user_id - on_call_layer_members.user_id - site_outages.site_id - escalation_targets.user_id - notification_digests.organization_id - on_call_notifications.user_id - alerts.site_outage_id (already existed, skipped) Without indexes, PostgreSQL must perform sequential scans for: - Referential integrity checks on DELETE/UPDATE of parent rows - JOIN operations on these columns - Can cause lock contention and slow queries Indexes created with CONCURRENTLY option to avoid blocking production tables during deployment. Migration uses @disable_ddl_transaction and @disable_migration_lock to ensure indexes are built without holding locks. Reviewed-on: graham/towerops-web#167
This commit is contained in:
parent
dba9a286d3
commit
d75eeb5389
1 changed files with 44 additions and 0 deletions
|
|
@ -0,0 +1,44 @@
|
|||
defmodule Towerops.Repo.Migrations.AddMissingFkIndexes do
|
||||
use Ecto.Migration
|
||||
|
||||
@disable_ddl_transaction true
|
||||
@disable_migration_lock true
|
||||
|
||||
def up do
|
||||
# Create indexes concurrently to avoid locking tables in production
|
||||
# These foreign keys were missing indexes, causing slow DELETEs/UPDATEs
|
||||
# on parent tables and slow JOINs
|
||||
|
||||
# on_call_overrides.user_id -> users.id
|
||||
create_if_not_exists index(:on_call_overrides, [:user_id], concurrently: true)
|
||||
|
||||
# on_call_layer_members.user_id -> users.id
|
||||
create_if_not_exists index(:on_call_layer_members, [:user_id], concurrently: true)
|
||||
|
||||
# site_outages.site_id -> sites.id
|
||||
create_if_not_exists index(:site_outages, [:site_id], concurrently: true)
|
||||
|
||||
# escalation_targets.user_id -> users.id
|
||||
create_if_not_exists index(:escalation_targets, [:user_id], concurrently: true)
|
||||
|
||||
# notification_digests.organization_id -> organizations.id
|
||||
create_if_not_exists index(:notification_digests, [:organization_id], concurrently: true)
|
||||
|
||||
# on_call_notifications.user_id -> users.id
|
||||
create_if_not_exists index(:on_call_notifications, [:user_id], concurrently: true)
|
||||
|
||||
# alerts.site_outage_id -> site_outages.id
|
||||
create_if_not_exists index(:alerts, [:site_outage_id], concurrently: true)
|
||||
end
|
||||
|
||||
def down do
|
||||
# Drop indexes in reverse order
|
||||
drop_if_exists index(:alerts, [:site_outage_id], concurrently: true)
|
||||
drop_if_exists index(:on_call_notifications, [:user_id], concurrently: true)
|
||||
drop_if_exists index(:notification_digests, [:organization_id], concurrently: true)
|
||||
drop_if_exists index(:escalation_targets, [:user_id], concurrently: true)
|
||||
drop_if_exists index(:site_outages, [:site_id], concurrently: true)
|
||||
drop_if_exists index(:on_call_layer_members, [:user_id], concurrently: true)
|
||||
drop_if_exists index(:on_call_overrides, [:user_id], concurrently: true)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue