Add manual SQL script for applying supplementary indexes migration
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
-- ================================================
|
||||
-- Jellyfin PostgreSQL Migration
|
||||
-- Migration: 20260227000000_AddSupplementaryIndexes
|
||||
-- Purpose: Add performance indexes for improved query performance
|
||||
-- ================================================
|
||||
--
|
||||
-- INSTRUCTIONS:
|
||||
-- 1. Connect to your Jellyfin PostgreSQL database
|
||||
-- 2. Run this script using psql, pgAdmin, or any PostgreSQL client
|
||||
-- 3. Verify indexes are created (see verification query at end)
|
||||
--
|
||||
-- ================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Check if migration was already applied
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM library."__EFMigrationsHistory"
|
||||
WHERE "MigrationId" = '20260227000000_AddSupplementaryIndexes'
|
||||
) THEN
|
||||
RAISE NOTICE 'Migration 20260227000000_AddSupplementaryIndexes already applied. Skipping...';
|
||||
ELSE
|
||||
RAISE NOTICE 'Applying migration 20260227000000_AddSupplementaryIndexes...';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ================================================
|
||||
-- Create Indexes (CONCURRENTLY - safe for production)
|
||||
-- ================================================
|
||||
|
||||
-- 1. Composite index for filtered library browsing (type + virtual + parent)
|
||||
-- Use case: Browse items by type in a specific library, excluding virtual items
|
||||
-- Improves queries like: "SELECT * FROM BaseItems WHERE Type='Movie' AND IsVirtualItem=false AND TopParentId='xyz'"
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_baseitems_type_isvirtualitem_topparentid
|
||||
ON library."BaseItems" ("Type", "IsVirtualItem", "TopParentId")
|
||||
WHERE "IsVirtualItem" = false;
|
||||
|
||||
-- 2. Index for folder hierarchy queries
|
||||
-- Use case: Navigate folder structures efficiently
|
||||
-- Improves queries like: "SELECT * FROM BaseItems WHERE TopParentId='xyz' AND IsFolder=true"
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_baseitems_topparentid_isfolder
|
||||
ON library."BaseItems" ("TopParentId", "IsFolder", "IsVirtualItem")
|
||||
WHERE "TopParentId" IS NOT NULL;
|
||||
|
||||
-- 3. Index for recently added content with filters
|
||||
-- Use case: "Recently Added" view across all libraries
|
||||
-- Improves queries like: "SELECT * FROM BaseItems WHERE IsVirtualItem=false ORDER BY DateCreated DESC"
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_baseitems_datecreated_filtered
|
||||
ON library."BaseItems" ("DateCreated" DESC, "Type", "IsVirtualItem")
|
||||
WHERE "DateCreated" IS NOT NULL AND "IsVirtualItem" = false;
|
||||
|
||||
-- 4. Index for reverse lookup (find items by genre/tag)
|
||||
-- Use case: "Show all items with genre 'Action'"
|
||||
-- Improves queries like: "SELECT ItemId FROM ItemValuesMap WHERE ItemValueId='action-genre-id'"
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_itemvaluesmap_itemvalueid_itemid
|
||||
ON library."ItemValuesMap" ("ItemValueId", "ItemId");
|
||||
|
||||
-- 5. Index for user-specific activity queries
|
||||
-- Use case: "Show activity for user X"
|
||||
-- Improves queries like: "SELECT * FROM ActivityLogs WHERE UserId='user-id' ORDER BY DateCreated DESC"
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM information_schema.tables
|
||||
WHERE table_schema = 'activitylog'
|
||||
AND table_name = 'ActivityLogs'
|
||||
) THEN
|
||||
RAISE NOTICE 'Creating activity log index...';
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_activitylogs_userid_datecreated
|
||||
ON activitylog."ActivityLogs" ("UserId", "DateCreated" DESC)
|
||||
WHERE "UserId" IS NOT NULL;
|
||||
ELSE
|
||||
RAISE NOTICE 'ActivityLogs table does not exist. Skipping activity log index.';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 6. Index for episode deduplication by PresentationUniqueKey
|
||||
-- Use case: Group and deduplicate episodes (used in GetItems queries)
|
||||
-- Improves queries like: "SELECT * FROM BaseItems WHERE Type='Episode' AND PresentationUniqueKey='xyz'"
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_baseitems_presentationuniquekey_episodes
|
||||
ON library."BaseItems" ("PresentationUniqueKey", "TopParentId", "IsVirtualItem")
|
||||
WHERE "Type" = 'MediaBrowser.Controller.Entities.TV.Episode' AND "PresentationUniqueKey" IS NOT NULL;
|
||||
|
||||
-- ================================================
|
||||
-- Update migration history
|
||||
-- ================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
INSERT INTO library."__EFMigrationsHistory" ("MigrationId", "ProductVersion")
|
||||
VALUES ('20260227000000_AddSupplementaryIndexes', '11.0.0')
|
||||
ON CONFLICT ("MigrationId") DO NOTHING;
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ================================================
|
||||
-- Verification Query
|
||||
-- ================================================
|
||||
-- Run this to verify all indexes were created successfully:
|
||||
|
||||
SELECT
|
||||
schemaname AS "Schema",
|
||||
tablename AS "Table",
|
||||
indexname AS "Index Name",
|
||||
indexdef AS "Definition"
|
||||
FROM pg_indexes
|
||||
WHERE indexname IN (
|
||||
'idx_baseitems_type_isvirtualitem_topparentid',
|
||||
'idx_baseitems_topparentid_isfolder',
|
||||
'idx_baseitems_datecreated_filtered',
|
||||
'idx_itemvaluesmap_itemvalueid_itemid',
|
||||
'idx_activitylogs_userid_datecreated',
|
||||
'idx_baseitems_presentationuniquekey_episodes'
|
||||
)
|
||||
ORDER BY schemaname, tablename, indexname;
|
||||
|
||||
-- Expected: 6 rows (or 5 if ActivityLogs table doesn't exist)
|
||||
Reference in New Issue
Block a user