-- 049_composite_indexes.sql -- Composite Indexes for Common Queries (BE-DB-010: Add composite indexes for common queries) -- Add indexes on (user_id, status), (playlist_id, track_id), etc. -- === TRACKS COMPOSITE INDEXES === -- Index for tracks by creator and visibility/public status CREATE INDEX IF NOT EXISTS idx_tracks_creator_id_is_public ON public.tracks(creator_id, is_public) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_tracks_creator_id_created_at ON public.tracks(creator_id, created_at DESC) WHERE deleted_at IS NULL; -- Index for tracks by status and created_at (for processing queue) CREATE INDEX IF NOT EXISTS idx_tracks_status_created_at ON public.tracks(status, created_at) WHERE status IN ('uploading', 'processing'); -- === PLAYLISTS COMPOSITE INDEXES === -- Index for playlists by user and visibility CREATE INDEX IF NOT EXISTS idx_playlists_user_id_is_public ON public.playlists(user_id, is_public) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_playlists_user_id_created_at ON public.playlists(user_id, created_at DESC) WHERE deleted_at IS NULL; -- === PLAYLIST_TRACKS COMPOSITE INDEXES === -- Index for playlist_tracks by playlist and track (for checking if track exists in playlist) -- Note: idx_playlist_tracks_playlist_id_position already exists, but we add (playlist_id, track_id) for existence checks CREATE INDEX IF NOT EXISTS idx_playlist_tracks_playlist_track ON public.playlist_tracks(playlist_id, track_id); -- === TRACK_LIKES COMPOSITE INDEXES === -- Index for track_likes by track and user (for checking if user liked track) CREATE INDEX IF NOT EXISTS idx_track_likes_track_user ON public.track_likes(track_id, user_id); -- === TRACK_COMMENTS COMPOSITE INDEXES === -- Index for track_comments by track and created_at (for listing comments) CREATE INDEX IF NOT EXISTS idx_track_comments_track_created_at ON public.track_comments(track_id, created_at DESC) WHERE deleted_at IS NULL; -- Index for track_comments by track and parent_id (for replies) CREATE INDEX IF NOT EXISTS idx_track_comments_track_parent ON public.track_comments(track_id, parent_id) WHERE parent_id IS NOT NULL AND deleted_at IS NULL; -- === MESSAGES COMPOSITE INDEXES === -- Index for messages by room and created_at (for listing messages in a room) -- Note: Table messages is created in 050_legacy_chat.sql, so we check if it exists first DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'messages' ) THEN CREATE INDEX IF NOT EXISTS idx_messages_room_created_at ON public.messages(room_id, created_at DESC) WHERE deleted_at IS NULL; END IF; END $$; -- === FOLLOWS COMPOSITE INDEXES === -- Index for follows by follower and created_at (for listing who a user follows) CREATE INDEX IF NOT EXISTS idx_follows_follower_created_at ON public.follows(follower_id, created_at DESC); -- Index for follows by followed and created_at (for listing followers) CREATE INDEX IF NOT EXISTS idx_follows_followed_created_at ON public.follows(followed_id, created_at DESC); -- === NOTIFICATIONS COMPOSITE INDEXES === -- Index for notifications by user and read status (for listing unread notifications) CREATE INDEX IF NOT EXISTS idx_notifications_user_read_created_at ON public.notifications(user_id, read, created_at DESC); -- === ANALYTICS COMPOSITE INDEXES === -- Index for analytics_events by event_name and created_at (already exists, but ensure it's there) -- Note: Check if idx_analytics_events_name_created exists, if not create it CREATE INDEX IF NOT EXISTS idx_analytics_events_name_created_at ON public.analytics_events(event_name, created_at DESC); -- Comments COMMENT ON INDEX idx_tracks_creator_id_is_public IS 'Composite index for filtering tracks by creator and public status'; COMMENT ON INDEX idx_playlists_user_id_is_public IS 'Composite index for filtering playlists by user and public status'; COMMENT ON INDEX idx_playlist_tracks_playlist_track IS 'Composite index for checking if track exists in playlist'; COMMENT ON INDEX idx_track_likes_track_user IS 'Composite index for checking if user liked a track'; -- Comment on messages index (only if table exists) DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'messages' ) AND EXISTS ( SELECT 1 FROM pg_indexes WHERE schemaname = 'public' AND indexname = 'idx_messages_room_created_at' ) THEN COMMENT ON INDEX idx_messages_room_created_at IS 'Composite index for listing messages in a room ordered by date'; END IF; END $$; COMMENT ON INDEX idx_notifications_user_read_created_at IS 'Composite index for listing notifications by user, read status, and date';