diff --git a/veza-backend-api/migrations/960_performance_indexes_v0124.sql b/veza-backend-api/migrations/960_performance_indexes_v0124.sql new file mode 100644 index 000000000..87945e696 --- /dev/null +++ b/veza-backend-api/migrations/960_performance_indexes_v0124.sql @@ -0,0 +1,96 @@ +-- v0.12.4: Performance & Scalabilité — Critical indexes for query optimization +-- Reference: ORIGIN_PERFORMANCE_TARGETS.md §8.4 + +-- ============================================================================ +-- USERS — Frequently queried by email, username, creation date +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); +CREATE INDEX IF NOT EXISTS idx_users_username ON users(username); +CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at DESC); + +-- ============================================================================ +-- TRACKS — Core entity, heavy read traffic +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_tracks_creator_id ON tracks(creator_id); +CREATE INDEX IF NOT EXISTS idx_tracks_genre ON tracks(genre); +CREATE INDEX IF NOT EXISTS idx_tracks_created_at ON tracks(created_at DESC); +CREATE INDEX IF NOT EXISTS idx_tracks_status_created ON tracks(status, created_at DESC) + WHERE deleted_at IS NULL; + +-- ============================================================================ +-- MESSAGES — Chat performance (room+time range queries) +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_messages_room_created ON messages(room_id, created_at DESC); +CREATE INDEX IF NOT EXISTS idx_messages_sender_id ON messages(sender_id); + +-- ============================================================================ +-- PLAYLISTS — Discovery and user playlists +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_playlists_creator_id ON playlists(creator_id); +CREATE INDEX IF NOT EXISTS idx_playlists_public_created ON playlists(is_public, created_at DESC) + WHERE deleted_at IS NULL; + +-- ============================================================================ +-- PLAYLIST TRACKS — Join table, ordering +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_playlist_tracks_playlist ON playlist_tracks(playlist_id, position); +CREATE INDEX IF NOT EXISTS idx_playlist_tracks_track ON playlist_tracks(track_id); + +-- ============================================================================ +-- FEED / SOCIAL — Follows, feed generation +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_follows_follower ON follows(follower_id); +CREATE INDEX IF NOT EXISTS idx_follows_following ON follows(following_id); + +-- ============================================================================ +-- COMMENTS — Track comments and replies +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_comments_track_created ON comments(track_id, created_at DESC) + WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_comments_user ON comments(user_id); + +-- ============================================================================ +-- NOTIFICATIONS — User notification inbox +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_notifications_user_created ON notifications(user_id, created_at DESC); +CREATE INDEX IF NOT EXISTS idx_notifications_user_unread ON notifications(user_id, is_read) + WHERE is_read = false; + +-- ============================================================================ +-- ANALYTICS — Creator dashboard queries +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_track_plays_track_date ON track_plays(track_id, played_at DESC); +CREATE INDEX IF NOT EXISTS idx_track_plays_user ON track_plays(user_id, played_at DESC); + +-- ============================================================================ +-- MARKETPLACE — Transactions and listings +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_marketplace_listings_status ON marketplace_listings(status, created_at DESC) + WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_marketplace_transactions_buyer ON marketplace_transactions(buyer_id, created_at DESC); +CREATE INDEX IF NOT EXISTS idx_marketplace_transactions_seller ON marketplace_transactions(seller_id, created_at DESC); + +-- ============================================================================ +-- EDUCATION — Course discovery and enrollment +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_courses_status_created ON courses(status, created_at DESC) + WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_course_enrollments_user ON course_enrollments(user_id, created_at DESC); + +-- ============================================================================ +-- FULL-TEXT SEARCH (GIN indexes for PostgreSQL text search) +-- ============================================================================ +CREATE INDEX IF NOT EXISTS idx_tracks_search_gin ON tracks + USING GIN(to_tsvector('english', COALESCE(title, '') || ' ' || COALESCE(description, ''))); +CREATE INDEX IF NOT EXISTS idx_users_search_gin ON users + USING GIN(to_tsvector('english', COALESCE(username, '') || ' ' || COALESCE(display_name, ''))); + +-- ============================================================================ +-- STATISTICS — Update planner statistics for optimal query plans +-- ============================================================================ +ANALYZE users; +ANALYZE tracks; +ANALYZE messages; +ANALYZE playlists; +ANALYZE follows; +ANALYZE notifications; diff --git a/veza-backend-api/migrations/960_performance_indexes_v0124_down.sql b/veza-backend-api/migrations/960_performance_indexes_v0124_down.sql new file mode 100644 index 000000000..a8b3fdb56 --- /dev/null +++ b/veza-backend-api/migrations/960_performance_indexes_v0124_down.sql @@ -0,0 +1,53 @@ +-- v0.12.4: Rollback performance indexes + +-- Users +DROP INDEX IF EXISTS idx_users_email; +DROP INDEX IF EXISTS idx_users_username; +DROP INDEX IF EXISTS idx_users_created_at; + +-- Tracks +DROP INDEX IF EXISTS idx_tracks_creator_id; +DROP INDEX IF EXISTS idx_tracks_genre; +DROP INDEX IF EXISTS idx_tracks_created_at; +DROP INDEX IF EXISTS idx_tracks_status_created; + +-- Messages +DROP INDEX IF EXISTS idx_messages_room_created; +DROP INDEX IF EXISTS idx_messages_sender_id; + +-- Playlists +DROP INDEX IF EXISTS idx_playlists_creator_id; +DROP INDEX IF EXISTS idx_playlists_public_created; + +-- Playlist Tracks +DROP INDEX IF EXISTS idx_playlist_tracks_playlist; +DROP INDEX IF EXISTS idx_playlist_tracks_track; + +-- Feed / Social +DROP INDEX IF EXISTS idx_follows_follower; +DROP INDEX IF EXISTS idx_follows_following; + +-- Comments +DROP INDEX IF EXISTS idx_comments_track_created; +DROP INDEX IF EXISTS idx_comments_user; + +-- Notifications +DROP INDEX IF EXISTS idx_notifications_user_created; +DROP INDEX IF EXISTS idx_notifications_user_unread; + +-- Analytics +DROP INDEX IF EXISTS idx_track_plays_track_date; +DROP INDEX IF EXISTS idx_track_plays_user; + +-- Marketplace +DROP INDEX IF EXISTS idx_marketplace_listings_status; +DROP INDEX IF EXISTS idx_marketplace_transactions_buyer; +DROP INDEX IF EXISTS idx_marketplace_transactions_seller; + +-- Education +DROP INDEX IF EXISTS idx_courses_status_created; +DROP INDEX IF EXISTS idx_course_enrollments_user; + +-- Full-text search +DROP INDEX IF EXISTS idx_tracks_search_gin; +DROP INDEX IF EXISTS idx_users_search_gin;