-- Performance indexes for production heavy load -- Run this migration before going to production with real users -- Articles - most frequently queried table CREATE INDEX IF NOT EXISTS idx_articles_published_at ON articles(published_at DESC) WHERE published = true; CREATE INDEX IF NOT EXISTS idx_articles_category_published ON articles(category_id, published_at DESC) WHERE published = true; CREATE INDEX IF NOT EXISTS idx_articles_slug ON articles(slug) WHERE slug IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_articles_featured ON articles(featured, published_at DESC) WHERE featured = true AND published = true; -- Players - frequently filtered and sorted CREATE INDEX IF NOT EXISTS idx_players_team_position ON players(team_id, position); CREATE INDEX IF NOT EXISTS idx_players_jersey_number ON players(jersey_number) WHERE jersey_number IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_players_active ON players(active) WHERE active = true; -- Newsletter subscriptions - queried for sends CREATE INDEX IF NOT EXISTS idx_newsletter_status ON newsletter_subscriptions(status) WHERE status = 'active'; CREATE INDEX IF NOT EXISTS idx_newsletter_preferences ON newsletter_subscriptions(preferences) WHERE preferences IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_newsletter_token ON newsletter_subscriptions(token) WHERE token IS NOT NULL; -- Contact messages - admin queries CREATE INDEX IF NOT EXISTS idx_contact_messages_unread ON contact_messages(is_read, created_at DESC) WHERE is_read = false; CREATE INDEX IF NOT EXISTS idx_contact_messages_category ON contact_messages(category_id, created_at DESC); -- Events/Activities - public queries CREATE INDEX IF NOT EXISTS idx_events_date ON events(event_date DESC) WHERE event_date IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_events_upcoming ON events(event_date ASC) WHERE event_date >= NOW(); -- Polls - frequently accessed CREATE INDEX IF NOT EXISTS idx_polls_active ON polls(active, created_at DESC) WHERE active = true; CREATE INDEX IF NOT EXISTS idx_poll_votes_poll_id ON poll_votes(poll_id, created_at DESC); CREATE INDEX IF NOT EXISTS idx_poll_votes_session ON poll_votes(session_token) WHERE session_token IS NOT NULL; -- Match overrides - FACR integration lookups CREATE INDEX IF NOT EXISTS idx_match_overrides_external_id ON match_overrides(external_match_id); CREATE INDEX IF NOT EXISTS idx_team_logo_overrides_external_id ON team_logo_overrides(external_team_id); -- Competition aliases - frequently joined CREATE INDEX IF NOT EXISTS idx_competition_aliases_code ON competition_aliases(external_code); CREATE INDEX IF NOT EXISTS idx_competition_aliases_order ON competition_aliases(display_order); -- Uploaded files - orphan detection and usage tracking CREATE INDEX IF NOT EXISTS idx_uploaded_files_created ON uploaded_files(created_at DESC); CREATE INDEX IF NOT EXISTS idx_file_usages_file_id ON file_usages(file_id); CREATE INDEX IF NOT EXISTS idx_file_usages_entity ON file_usages(entity_type, entity_id); -- Short links - redirect lookups CREATE INDEX IF NOT EXISTS idx_short_links_code ON short_links(code) WHERE active = true; CREATE INDEX IF NOT EXISTS idx_link_clicks_short_link_id ON link_clicks(short_link_id, created_at DESC); -- Navigation - public queries (cached but index helps) CREATE INDEX IF NOT EXISTS idx_navigation_items_order ON navigation_items(display_order, parent_id); CREATE INDEX IF NOT EXISTS idx_navigation_items_visible ON navigation_items(visible) WHERE visible = true; -- Email tracking CREATE INDEX IF NOT EXISTS idx_email_logs_sent_at ON email_logs(sent_at DESC); CREATE INDEX IF NOT EXISTS idx_email_events_log_id ON email_events(email_log_id, event_type, created_at DESC); -- Audit logs (if heavy usage) CREATE INDEX IF NOT EXISTS idx_audit_logs_timestamp ON audit_logs(timestamp DESC) WHERE timestamp IS NOT NULL; -- Page element configs - editor queries CREATE INDEX IF NOT EXISTS idx_page_elements_name ON page_element_configs(element_name) WHERE element_name IS NOT NULL; -- VACUUM ANALYZE to update statistics after index creation VACUUM ANALYZE;