-- 048_search_indexes.sql -- Search Indexes (BE-DB-009: Add indexes for search queries) -- Add full-text search indexes on tracks.title, tracks.artist, users.username -- === TRACKS SEARCH INDEXES === -- Index for searching by title (case-insensitive) CREATE INDEX IF NOT EXISTS idx_tracks_title_gin ON public.tracks USING GIN(to_tsvector('english', title)); -- Index for searching by artist (case-insensitive) CREATE INDEX IF NOT EXISTS idx_tracks_artist_gin ON public.tracks USING GIN(to_tsvector('english', COALESCE(artist, ''))); -- B-tree indexes for exact matches and prefix searches CREATE INDEX IF NOT EXISTS idx_tracks_title_btree ON public.tracks(title) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_tracks_artist_btree ON public.tracks(artist) WHERE deleted_at IS NULL AND artist IS NOT NULL; -- === USERS SEARCH INDEXES === -- Index for searching by username (case-insensitive) -- Note: idx_users_username already exists as UNIQUE index, but we add a GIN index for full-text search CREATE INDEX IF NOT EXISTS idx_users_username_gin ON public.users USING GIN(to_tsvector('english', username)) WHERE deleted_at IS NULL; -- B-tree index for prefix searches on username (if not already covered by unique index) -- The unique index idx_users_username already exists, but we add a separate index for LIKE queries CREATE INDEX IF NOT EXISTS idx_users_username_lower ON public.users(LOWER(username)) WHERE deleted_at IS NULL; -- Comments COMMENT ON INDEX idx_tracks_title_gin IS 'Full-text search index on track titles'; COMMENT ON INDEX idx_tracks_artist_gin IS 'Full-text search index on track artists'; COMMENT ON INDEX idx_tracks_title_btree IS 'B-tree index for exact and prefix searches on track titles'; COMMENT ON INDEX idx_tracks_artist_btree IS 'B-tree index for exact and prefix searches on track artists'; COMMENT ON INDEX idx_users_username_gin IS 'Full-text search index on usernames'; COMMENT ON INDEX idx_users_username_lower IS 'Case-insensitive index for username prefix searches';