diff --git a/libs/shared/database/src/lib/connection.ts b/libs/shared/database/src/lib/connection.ts index 451781cc4..213571181 100644 --- a/libs/shared/database/src/lib/connection.ts +++ b/libs/shared/database/src/lib/connection.ts @@ -147,6 +147,13 @@ const CREATE_TABLE_STATEMENTS = [ `CREATE INDEX IF NOT EXISTS idx_content_xtream ON content(xtream_id)`, `CREATE INDEX IF NOT EXISTS idx_content_type_added ON content(type, added)`, `CREATE INDEX IF NOT EXISTS idx_categories_type ON categories(type)`, + // Partial covering index for visible categories — supports the dashboard's + // getGlobalRecentlyAdded plus searchContent/globalSearch when excludeHidden + // is set. SQLite can satisfy the join (category_id PK lookup) plus the + // hidden = 0 filter directly from this index without touching the + // categories row, and hidden categories are absent so they're skipped + // before any row lookup. + `CREATE INDEX IF NOT EXISTS idx_categories_visible ON categories(id, playlist_id, type) WHERE hidden = 0`, `CREATE UNIQUE INDEX IF NOT EXISTS favorites_content_playlist_unique ON favorites(content_id, playlist_id)`, `CREATE INDEX IF NOT EXISTS favorites_playlist_idx ON favorites(playlist_id)`, `CREATE INDEX IF NOT EXISTS favorites_content_idx ON favorites(content_id)`, diff --git a/libs/shared/database/src/lib/schema.ts b/libs/shared/database/src/lib/schema.ts index aa9b2a3e6..c6c3c2b7e 100644 --- a/libs/shared/database/src/lib/schema.ts +++ b/libs/shared/database/src/lib/schema.ts @@ -72,6 +72,12 @@ export const categories = sqliteTable( playlistTypeXtreamUnique: uniqueIndex( 'categories_playlist_type_xtream_unique' ).on(table.playlistId, table.type, table.xtreamId), + // Partial covering index for visible categories — see connection.ts + // for the full rationale. SQLite can satisfy joins + hidden filter + // directly from this index for the dashboard / search queries. + visibleIdx: index('idx_categories_visible') + .on(table.id, table.playlistId, table.type) + .where(sql`hidden = 0`), }) );