feat: add database indexes for performance optimization across multiple tables

This commit is contained in:
g0ldyy
2025-09-06 20:40:33 +02:00
parent 4b96323c91
commit c80607871e
+249
View File
@@ -320,6 +320,255 @@ async def setup_database():
"""
)
# =============================================================================
# TORRENTS TABLE INDEXES - Most critical for performance
# =============================================================================
# Primary lookup index: media_id + season + episode + timestamp (cache TTL filter)
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_torrents_media_cache_lookup
ON torrents (media_id, season, episode, timestamp)
"""
)
# Info hash lookup for playback (very frequent)
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_torrents_info_hash
ON torrents (info_hash)
"""
)
# Analytics queries: tracker-based aggregation
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_torrents_tracker_analytics
ON torrents (tracker, seeders, size)
"""
)
# Size filtering for user preferences
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_torrents_size_filter
ON torrents (size, timestamp)
"""
)
# Seeders ordering for quality ranking
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_torrents_seeders_desc
ON torrents (seeders DESC, timestamp)
"""
)
# =============================================================================
# DEBRID_AVAILABILITY TABLE INDEXES - Critical for cache performance
# =============================================================================
# Primary cache lookup: service + info_hash list + timestamp
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_debrid_service_hash_cache
ON debrid_availability (debrid_service, info_hash, timestamp)
"""
)
# Season/episode filtering for series content
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_debrid_season_episode_filter
ON debrid_availability (debrid_service, season, episode, timestamp)
"""
)
# Service-based analytics and cleanup
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_debrid_service_timestamp
ON debrid_availability (debrid_service, timestamp)
"""
)
# Title filtering for OffCloud special case
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_debrid_title_filter
ON debrid_availability (debrid_service, info_hash, title, timestamp)
"""
)
# =============================================================================
# DOWNLOAD_LINKS_CACHE TABLE INDEXES - Playback performance
# =============================================================================
# Primary playback lookup: debrid_key + info_hash + season + episode
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_download_links_playback
ON download_links_cache (debrid_key, info_hash, season, episode, timestamp)
"""
)
# Timestamp-based cleanup
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_download_links_cleanup
ON download_links_cache (timestamp)
"""
)
# =============================================================================
# METADATA_CACHE TABLE INDEXES - Metadata performance
# =============================================================================
# Primary cache lookup: media_id + timestamp
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_metadata_cache_lookup
ON metadata_cache (media_id, timestamp)
"""
)
# Title search for metadata discovery
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_metadata_title_search
ON metadata_cache (title, year, timestamp)
"""
)
# =============================================================================
# FIRST_SEARCHES TABLE INDEXES - Search optimization
# =============================================================================
# Primary search check: media_id (already PRIMARY KEY, but explicit for clarity)
# Media ID is already PRIMARY KEY, so focusing on timestamp for TTL cleanup
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_first_searches_cleanup
ON first_searches (timestamp)
"""
)
# =============================================================================
# ACTIVE_CONNECTIONS TABLE INDEXES - Admin dashboard performance
# =============================================================================
# Admin dashboard ordering: timestamp DESC (most recent first)
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_connections_timestamp_desc
ON active_connections (timestamp DESC)
"""
)
# IP-based filtering and monitoring
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_connections_ip_filter
ON active_connections (ip, timestamp)
"""
)
# Connection monitoring by content type
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_connections_content_monitoring
ON active_connections (content, timestamp)
"""
)
# =============================================================================
# SCRAPE_LOCKS TABLE INDEXES - Lock management
# =============================================================================
# Expired locks cleanup: expires_at < current_time
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_scrape_locks_expires
ON scrape_locks (expires_at)
"""
)
# Instance-based lock monitoring
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_scrape_locks_instance
ON scrape_locks (instance_id, timestamp)
"""
)
# =============================================================================
# ADMIN_SESSIONS TABLE INDEXES - Authentication performance
# =============================================================================
# Session cleanup: expires_at < current_time
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_admin_sessions_expires
ON admin_sessions (expires_at)
"""
)
# =============================================================================
# BACKGROUND_SCRAPER_STATE TABLE INDEXES - Scraper performance
# =============================================================================
# Media type filtering for scraper analytics
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_scraper_state_media_type
ON background_scraper_state (media_type, scraped_at)
"""
)
# Scraping timestamp for progress tracking
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_scraper_state_scraped_at
ON background_scraper_state (scraped_at)
"""
)
# Failed attempts monitoring
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_scraper_state_failures
ON background_scraper_state (scrape_failed_attempts, scraped_at)
"""
)
# =============================================================================
# COMPOSITE INDEXES FOR COMPLEX QUERIES
# =============================================================================
# Torrents: media + quality filtering + cache validity
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_torrents_quality_cache
ON torrents (media_id, seeders DESC, size DESC, timestamp)
"""
)
# Debrid: comprehensive availability lookup
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_debrid_comprehensive
ON debrid_availability (debrid_service, info_hash, season, episode, size, timestamp)
"""
)
# Background scraper: comprehensive state tracking
await database.execute(
"""
CREATE INDEX IF NOT EXISTS idx_scraper_comprehensive
ON background_scraper_state (media_type, total_torrents_found, scraped_at)
"""
)
if settings.DATABASE_TYPE == "sqlite":
await database.execute("PRAGMA busy_timeout=30000") # 30 seconds timeout
await database.execute("PRAGMA journal_mode=WAL")