-- 0008_query_indexes.sql — index the hot read paths. -- -- These exist so the home screen and library browse are index-ordered instead -- of sorting the whole library on every request. Each read path filters out -- missing rows and orders on a column that had no supporting index, so SQLite -- built and sorted the entire result set per page load. The column order below -- mirrors the filter-then-sort shape of each query: the equality columns first, -- then the ordering column, so the sort is satisfied by the index walk. -- Browse: list a library's present items in display order. CREATE INDEX idx_items_library_missing_sort ON media_items(library_id, missing, sort_title); -- Home: "Recently added" and the suggestion shelves, newest first. CREATE INDEX idx_items_library_missing_added ON media_items(library_id, missing, added_at DESC); -- Explore: a per-kind id range scan wants kind and id together. CREATE INDEX idx_items_kind_missing_id ON media_items(kind, missing, id); -- Deliberately NOT indexed: the Continue shelf's `user_id + finished = 0` filter. -- A candidate index on (user_id, finished, updated_at DESC) was built, benchmarked -- against 30k progress rows with ANALYZE statistics, and never chosen — the query -- planner prefers the primary-key autoindex, because `finished = 0` selects the -- MAJORITY of a user's rows (people abandon more than they finish), so leading an -- index with `finished` has almost no selectivity. It would cost a write on every -- progress save, which happens every ~2s during playback, for no read benefit.