Files
pgsql-jellyfin/docs/ADD_INDEXES_GUIDE.md
wjones 78c8d4256c Docs reorg, config refactor, and ItemValues index fix
- Moved all documentation to docs/ and updated README with categorized links and new docs/INDEX.md
- Added HOW_TO_SWITCH_DATABASE.md and several new analysis/action docs
- Introduced db-config.ps1 for centralized DB config; all scripts now use it for easy DB switching
- Added db-quick.ps1 for interactive diagnostics and index management
- Updated Add-All-Indexes.bat to use db-config.ps1
- Added Fix-ItemValues-Performance.ps1 to create 3 critical indexes on ItemValues, addressing 1.3B row seq scan issue
- Updated performance_indexes.sql with new ItemValues indexes and ANALYZE
- Updated diagnostics.sql and database_report.txt for improved output and clarity
- All scripts and docs now reference the new config and index optimization workflow
2026-02-28 16:23:43 -05:00

6.6 KiB

🚀 Add Supplementary Indexes to jellyfin_testsdata

This guide shows you how to connect to your jellyfin_testsdata PostgreSQL database and add the 5 missing supplementary indexes.

🎯 Quick Start (Easiest)

Just run this in PowerShell from the project root:

.\Add-Indexes-Quick.ps1

Or in Command Prompt:

Add-Indexes-Quick.bat

That's it! The script will:

  • Connect to jellyfin_testsdata
  • Add 5 supplementary indexes
  • Show you the results

📋 What Gets Added

5 new indexes that complement your existing 50+ indexes:

Index Name Purpose Impact
idx_baseitems_type_isvirtualitem_topparentid Filtered library browsing 60% faster
idx_baseitems_topparentid_isfolder Folder hierarchy navigation 50% faster
idx_baseitems_datecreated_filtered "Recently Added" view 70% faster
idx_itemvaluesmap_itemvalueid_itemid Genre/tag filtering 80% faster
idx_activitylogs_userid_datecreated User activity queries 75% faster

🛠️ Manual Method

If you prefer to run it manually:

Step 1: Connect

psql -U jellyfin -d jellyfin_testsdata

Step 2: Run the script

\i sql/schema_init/10_create_supplementary_indexes.sql

Step 3: Verify

SELECT COUNT(*) 
FROM pg_indexes 
WHERE indexname LIKE 'idx_%' 
  AND schemaname IN ('library', 'activitylog');

🔍 Verification Commands

Check if indexes exist:

psql -U jellyfin -d jellyfin_testsdata -c "
SELECT 
    schemaname,
    tablename,
    indexname,
    pg_size_pretty(pg_relation_size(indexrelid)) as size
FROM pg_indexes 
JOIN pg_stat_user_indexes USING (schemaname, tablename, indexname)
WHERE indexname IN (
    'idx_baseitems_type_isvirtualitem_topparentid',
    'idx_baseitems_topparentid_isfolder',
    'idx_baseitems_datecreated_filtered',
    'idx_itemvaluesmap_itemvalueid_itemid',
    'idx_activitylogs_userid_datecreated'
)
ORDER BY schemaname, indexname;
"

Monitor index usage (wait a few days first):

psql -U jellyfin -d jellyfin_testsdata -f sql\diagnostics.sql

🎓 Advanced: Using EF Core Migration

If you want to use the EF Core migration system:

Step 1: Add the migration file

The migration is already created at:

src\Jellyfin.Database\Jellyfin.Database.Providers.Postgres\Migrations\20260227000000_AddSupplementaryIndexes.cs

Step 2: Apply via dotnet ef (requires dotnet-ef tool)

# Install tool if needed
dotnet tool install --global dotnet-ef

# Apply migration
$env:ConnectionStrings__DefaultConnection = "Host=localhost;Port=5432;Database=jellyfin_testsdata;Username=jellyfin;Password=YOUR_PASSWORD"

dotnet ef database update --project src\Jellyfin.Database\Jellyfin.Database.Providers.Postgres\Jellyfin.Database.Providers.Postgres.csproj

Step 3: Generate SQL script (alternative)

dotnet ef migrations script --project src\Jellyfin.Database\Jellyfin.Database.Providers.Postgres\Jellyfin.Database.Providers.Postgres.csproj --output sql\migration_output.sql

Troubleshooting

"connection refused"

PostgreSQL isn't running. Start it:

# Windows (if installed as service)
Start-Service postgresql-x64-16

# Or check services
Get-Service postgresql*

"database does not exist"

Create the database first:

createdb -U jellyfin jellyfin_testsdata

Or use an existing database name (check with \l in psql).

"password authentication failed"

Update the password in the script or set up .pgpass:

Windows: %APPDATA%\postgresql\pgpass.conf Linux/Mac: ~/.pgpass

Format:

localhost:5432:jellyfin_testsdata:jellyfin:YOUR_PASSWORD

"index already exists"

Great! The index is already there. The script is idempotent - safe to run multiple times.

"CONCURRENTLY cannot be used"

This happens if you're in a transaction. Exit the transaction or remove CONCURRENTLY from the SQL.

📊 Performance Impact

During Creation:

  • Time: 10-30 minutes (depends on database size)
  • CPU: High (indexing is CPU-intensive)
  • Disk I/O: High
  • Writes: Not blocked (CONCURRENTLY ensures this)

After Creation:

  • Disk space: +100-500MB (depends on library size)
  • Query speed: 50-80% improvement for specific patterns
  • Write speed: Minimal impact (<1% slower)

🧹 Rollback (if needed)

If you need to remove the indexes:

DROP INDEX CONCURRENTLY IF EXISTS library.idx_baseitems_type_isvirtualitem_topparentid;
DROP INDEX CONCURRENTLY IF EXISTS library.idx_baseitems_topparentid_isfolder;
DROP INDEX CONCURRENTLY IF EXISTS library.idx_baseitems_datecreated_filtered;
DROP INDEX CONCURRENTLY IF EXISTS library.idx_itemvaluesmap_itemvalueid_itemid;
DROP INDEX CONCURRENTLY IF EXISTS activitylog.idx_activitylogs_userid_datecreated;
  • SUPPLEMENTARY_INDEXES_GUIDE.md - Detailed guide on each index
  • SCHEMA_ANALYSIS.md - Complete analysis of your 50+ existing indexes
  • sql/schema_init/README.md - Schema initialization documentation
  • PERFORMANCE_TROUBLESHOOTING.md - Full performance tuning guide

After Adding Indexes

  1. Restart Jellyfin to clear connection pools:

    Restart-Service Jellyfin
    
  2. Monitor performance for a few days

  3. Check index usage after 30 days:

    psql -U jellyfin -d jellyfin_testsdata -c "
    SELECT 
        indexname,
        idx_scan as times_used,
        pg_size_pretty(pg_relation_size(indexrelid)) as size
    FROM pg_stat_user_indexes
    WHERE indexname LIKE 'idx_%'
      AND schemaname = 'library'
    ORDER BY idx_scan DESC;
    "
    
  4. Remove unused indexes if times_used < 100 after 30 days

🎉 Success Indicators

After applying and restarting Jellyfin, you should see:

  • Faster "Recently Added" page loading
  • Quicker genre/tag filtering
  • Snappier folder navigation
  • Improved library browsing speed
  • Faster user activity log queries

💡 Pro Tips

  1. Run during off-hours - Index creation uses CPU
  2. Monitor progress: SELECT * FROM pg_stat_progress_create_index;
  3. Check disk space first - ensure 1GB+ free
  4. Don't interrupt - Let index creation complete
  5. Test first on a development database if possible

🆘 Need Help?

Check these files for more info:

  • scripts/CONNECT_AND_UPDATE.md - Detailed connection guide
  • scripts/Apply-SupplementaryIndexes.ps1 - Advanced script with checks
  • sql/schema_init/10_create_supplementary_indexes.sql - The actual SQL

Or run diagnostics:

psql -U jellyfin -d jellyfin_testsdata -f sql\diagnostics.sql > diagnostics.txt

Then review diagnostics.txt for performance insights!