91 lines
2.6 KiB
Elixir
91 lines
2.6 KiB
Elixir
defmodule Aprsme.Repo.Migrations.CompleteOptimizedIndexes do
|
|
use Ecto.Migration
|
|
@disable_ddl_transaction true
|
|
@disable_migration_lock true
|
|
|
|
def up do
|
|
# Add has_weather column without GENERATED clause first
|
|
# We'll populate it with a trigger instead
|
|
execute """
|
|
ALTER TABLE packets
|
|
ADD COLUMN IF NOT EXISTS has_weather boolean DEFAULT false
|
|
"""
|
|
|
|
# Create trigger to maintain has_weather
|
|
execute """
|
|
CREATE OR REPLACE FUNCTION update_has_weather()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.has_weather := (
|
|
NEW.temperature IS NOT NULL OR
|
|
NEW.humidity IS NOT NULL OR
|
|
NEW.pressure IS NOT NULL OR
|
|
NEW.wind_speed IS NOT NULL OR
|
|
NEW.wind_direction IS NOT NULL OR
|
|
NEW.rain_1h IS NOT NULL
|
|
);
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
"""
|
|
|
|
execute """
|
|
DROP TRIGGER IF EXISTS update_has_weather_trigger ON packets;
|
|
"""
|
|
|
|
execute """
|
|
CREATE TRIGGER update_has_weather_trigger
|
|
BEFORE INSERT OR UPDATE ON packets
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_has_weather();
|
|
"""
|
|
|
|
# Update existing rows in batches to avoid timeout
|
|
execute """
|
|
UPDATE packets
|
|
SET has_weather = (
|
|
temperature IS NOT NULL OR
|
|
humidity IS NOT NULL OR
|
|
pressure IS NOT NULL OR
|
|
wind_speed IS NOT NULL OR
|
|
wind_direction IS NOT NULL OR
|
|
rain_1h IS NOT NULL
|
|
)
|
|
WHERE id IN (
|
|
SELECT id FROM packets
|
|
WHERE has_weather IS NULL
|
|
LIMIT 100000
|
|
);
|
|
"""
|
|
|
|
# Create remaining indexes
|
|
execute """
|
|
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_packets_has_weather
|
|
ON packets (has_weather, sender, received_at DESC)
|
|
WHERE has_weather = true
|
|
"""
|
|
|
|
execute """
|
|
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_packets_region_position_time
|
|
ON packets (region, has_position, received_at DESC)
|
|
WHERE has_position = true AND region IS NOT NULL
|
|
"""
|
|
|
|
execute """
|
|
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_packets_datatype_sender_time
|
|
ON packets (data_type, sender, received_at DESC)
|
|
"""
|
|
|
|
# Analyze the table to update statistics
|
|
execute "ANALYZE packets;"
|
|
end
|
|
|
|
def down do
|
|
execute "DROP INDEX IF EXISTS idx_packets_datatype_sender_time;"
|
|
execute "DROP INDEX IF EXISTS idx_packets_region_position_time;"
|
|
execute "DROP INDEX IF EXISTS idx_packets_has_weather;"
|
|
execute "DROP TRIGGER IF EXISTS update_has_weather_trigger ON packets;"
|
|
execute "DROP FUNCTION IF EXISTS update_has_weather();"
|
|
execute "ALTER TABLE packets DROP COLUMN IF EXISTS has_weather;"
|
|
end
|
|
end
|