This commit is contained in:
Tomas Dvorak
2025-11-02 01:04:02 +01:00
parent ac886502e0
commit b9cea0cd77
153 changed files with 43713 additions and 1700 deletions
@@ -0,0 +1,47 @@
-- Rollback performance indexes
DROP INDEX IF EXISTS idx_articles_published_at;
DROP INDEX IF EXISTS idx_articles_category_published;
DROP INDEX IF EXISTS idx_articles_slug;
DROP INDEX IF EXISTS idx_articles_featured;
DROP INDEX IF EXISTS idx_players_team_position;
DROP INDEX IF EXISTS idx_players_jersey_number;
DROP INDEX IF EXISTS idx_players_active;
DROP INDEX IF EXISTS idx_newsletter_status;
DROP INDEX IF EXISTS idx_newsletter_preferences;
DROP INDEX IF EXISTS idx_newsletter_token;
DROP INDEX IF EXISTS idx_contact_messages_unread;
DROP INDEX IF EXISTS idx_contact_messages_category;
DROP INDEX IF EXISTS idx_events_date;
DROP INDEX IF EXISTS idx_events_upcoming;
DROP INDEX IF EXISTS idx_polls_active;
DROP INDEX IF EXISTS idx_poll_votes_poll_id;
DROP INDEX IF EXISTS idx_poll_votes_session;
DROP INDEX IF EXISTS idx_match_overrides_external_id;
DROP INDEX IF EXISTS idx_team_logo_overrides_external_id;
DROP INDEX IF EXISTS idx_competition_aliases_code;
DROP INDEX IF EXISTS idx_competition_aliases_order;
DROP INDEX IF EXISTS idx_uploaded_files_created;
DROP INDEX IF EXISTS idx_file_usages_file_id;
DROP INDEX IF EXISTS idx_file_usages_entity;
DROP INDEX IF EXISTS idx_short_links_code;
DROP INDEX IF EXISTS idx_link_clicks_link_id;
DROP INDEX IF EXISTS idx_navigation_items_order;
DROP INDEX IF EXISTS idx_navigation_items_visible;
DROP INDEX IF EXISTS idx_email_logs_sent_at;
DROP INDEX IF EXISTS idx_email_events_log_id;
DROP INDEX IF EXISTS idx_audit_logs_timestamp;
DROP INDEX IF EXISTS idx_page_elements_name;
@@ -0,0 +1,65 @@
-- 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;
@@ -0,0 +1,21 @@
-- Enable pg_trgm for fast LIKE/ILIKE queries
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-- Trigram indexes for articles title/content (case-insensitive search)
CREATE INDEX IF NOT EXISTS idx_articles_title_trgm ON articles USING gin (lower(title) gin_trgm_ops);
CREATE INDEX IF NOT EXISTS idx_articles_content_trgm ON articles USING gin (lower(content) gin_trgm_ops);
-- Email logs composite index to accelerate recipient history lookups
CREATE INDEX IF NOT EXISTS idx_email_logs_recipient_created ON email_logs (recipient_email, created_at DESC);
-- Email events quick filter by type
CREATE INDEX IF NOT EXISTS idx_email_events_type ON email_events (event_type);
-- Newsletter sent log frequency by type and time
CREATE INDEX IF NOT EXISTS idx_newsletter_sent_log_type_time ON newsletter_sent_log (newsletter_type, sent_at DESC);
-- Match notifications lookups by match and type
CREATE INDEX IF NOT EXISTS idx_match_notifications_match_type ON match_notifications (match_id, notification_type);
-- Blog notifications listing by sent time
CREATE INDEX IF NOT EXISTS idx_blog_notifications_sent_at ON blog_notifications (sent_at DESC);