129 lines
5.9 KiB
SQL
129 lines
5.9 KiB
SQL
-- Migration: Add performance indexes for notification system
|
|
-- Purpose: Optimize queue processing queries and recipient lookups
|
|
-- Date: 2025-10-16
|
|
|
|
-- ==================================================================
|
|
-- 1. Composite index for queue processing
|
|
-- ==================================================================
|
|
-- This index optimizes the main queue processing query that filters by:
|
|
-- - status (queued/processing)
|
|
-- - scheduled_for (less than or equal to current time)
|
|
-- - priority (for ordering)
|
|
-- - last_attempt_at (for timeout recovery)
|
|
|
|
-- Check if index exists, drop if it does, then create
|
|
SET @exist := (SELECT COUNT(*) FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name = 'notification_queue'
|
|
AND index_name = 'idx_queue_processing_composite');
|
|
SET @sqlstmt := IF(@exist > 0,
|
|
'SELECT "Index idx_queue_processing_composite already exists"',
|
|
'CREATE INDEX idx_queue_processing_composite ON notification_queue(status, scheduled_for, priority, last_attempt_at)');
|
|
PREPARE stmt FROM @sqlstmt;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- ==================================================================
|
|
-- 2. Index for stuck job recovery
|
|
-- ==================================================================
|
|
-- Note: WHERE clause not supported in MySQL, using regular index instead
|
|
|
|
SET @exist := (SELECT COUNT(*) FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name = 'notification_queue'
|
|
AND index_name = 'idx_queue_stuck_recovery');
|
|
SET @sqlstmt := IF(@exist > 0,
|
|
'SELECT "Index idx_queue_stuck_recovery already exists"',
|
|
'CREATE INDEX idx_queue_stuck_recovery ON notification_queue(status, last_attempt_at)');
|
|
PREPARE stmt FROM @sqlstmt;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- ==================================================================
|
|
-- 3. Composite index for recipient status tracking
|
|
-- ==================================================================
|
|
|
|
SET @exist := (SELECT COUNT(*) FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name = 'notification_recipients'
|
|
AND index_name = 'idx_recipients_notification_status');
|
|
SET @sqlstmt := IF(@exist > 0,
|
|
'SELECT "Index idx_recipients_notification_status already exists"',
|
|
'CREATE INDEX idx_recipients_notification_status ON notification_recipients(notification_id, status)');
|
|
PREPARE stmt FROM @sqlstmt;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- ==================================================================
|
|
-- 4. Index for notification logs by notification and date
|
|
-- ==================================================================
|
|
|
|
SET @exist := (SELECT COUNT(*) FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name = 'notification_logs'
|
|
AND index_name = 'idx_logs_notification_created');
|
|
SET @sqlstmt := IF(@exist > 0,
|
|
'SELECT "Index idx_logs_notification_created already exists"',
|
|
'CREATE INDEX idx_logs_notification_created ON notification_logs(notification_id, created_at)');
|
|
PREPARE stmt FROM @sqlstmt;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- ==================================================================
|
|
-- 5. Index for notification logs by status and date
|
|
-- ==================================================================
|
|
|
|
SET @exist := (SELECT COUNT(*) FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name = 'notification_logs'
|
|
AND index_name = 'idx_logs_status_created');
|
|
SET @sqlstmt := IF(@exist > 0,
|
|
'SELECT "Index idx_logs_status_created already exists"',
|
|
'CREATE INDEX idx_logs_status_created ON notification_logs(status, created_at)');
|
|
PREPARE stmt FROM @sqlstmt;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- ==================================================================
|
|
-- 6. Index for notification delivery config lookups
|
|
-- ==================================================================
|
|
|
|
SET @exist := (SELECT COUNT(*) FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name = 'notification_delivery_config'
|
|
AND index_name = 'idx_delivery_config_channel_enabled');
|
|
SET @sqlstmt := IF(@exist > 0,
|
|
'SELECT "Index idx_delivery_config_channel_enabled already exists"',
|
|
'CREATE INDEX idx_delivery_config_channel_enabled ON notification_delivery_config(channel_type, is_enabled)');
|
|
PREPARE stmt FROM @sqlstmt;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- ==================================================================
|
|
-- 7. Index for queue items by recipient
|
|
-- ==================================================================
|
|
|
|
SET @exist := (SELECT COUNT(*) FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name = 'notification_queue'
|
|
AND index_name = 'idx_queue_recipient');
|
|
SET @sqlstmt := IF(@exist > 0,
|
|
'SELECT "Index idx_queue_recipient already exists"',
|
|
'CREATE INDEX idx_queue_recipient ON notification_queue(recipient_id)');
|
|
PREPARE stmt FROM @sqlstmt;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- ==================================================================
|
|
-- Verify indexes were created
|
|
-- ==================================================================
|
|
SELECT
|
|
table_name,
|
|
index_name,
|
|
column_name
|
|
FROM information_schema.statistics
|
|
WHERE table_schema = DATABASE()
|
|
AND table_name IN ('notification_queue', 'notification_recipients', 'notification_logs', 'notification_delivery_config')
|
|
AND index_name LIKE 'idx_%'
|
|
ORDER BY table_name, index_name, seq_in_index;
|