-- =====================================================================
-- Script de Optimización para scanning_report_daily_full
-- Propósito: Mejorar el rendimiento del widget "Comparativa entre Sucursales"
-- Fecha: 2025-10-21
-- =====================================================================

-- IMPORTANTE: Este script asume que scanning_report_daily_full es una VISTA MATERIALIZADA
-- Si es una vista regular, se deben crear índices en las tablas subyacentes

-- =====================================================================
-- Paso 1: Verificar si la vista es materializada
-- =====================================================================
SELECT
    schemaname,
    matviewname,
    definition
FROM pg_matviews
WHERE matviewname = 'scanning_report_daily_full';

-- Si el resultado está vacío, es una vista regular, no materializada
-- En ese caso, usar el script alternativo al final de este archivo

-- =====================================================================
-- Paso 2: Crear índices en la vista materializada (si existe)
-- =====================================================================

-- Índice compuesto principal: NetworkId + DetectionDate
-- Este índice optimiza las queries más comunes del widget
CREATE INDEX IF NOT EXISTS idx_scanning_report_network_date
ON scanning_report_daily_full (network_id, detection_date DESC);

-- Índice para filtros por rango de fechas
CREATE INDEX IF NOT EXISTS idx_scanning_report_detection_date
ON scanning_report_daily_full (detection_date DESC);

-- Índice para filtro por tipo de persona (PasserBy, Visitor)
CREATE INDEX IF NOT EXISTS idx_scanning_report_person_type
ON scanning_report_daily_full (person_type);

-- Índice compuesto para análisis por red y tipo de persona
CREATE INDEX IF NOT EXISTS idx_scanning_report_network_person
ON scanning_report_daily_full (network_id, person_type, detection_date DESC);

-- Índice para búsquedas por MAC address (reportes individuales)
CREATE INDEX IF NOT EXISTS idx_scanning_report_mac
ON scanning_report_daily_full (mac_address);

-- =====================================================================
-- Paso 3: Configurar auto-refresh de la vista materializada (OPCIONAL)
-- =====================================================================
-- NOTA: PostgreSQL no tiene auto-refresh nativo. Esto requiere un job externo.
-- Ejemplo usando pg_cron (si está instalado):

/*
-- Instalar pg_cron primero:
CREATE EXTENSION IF NOT EXISTS pg_cron;

-- Programar refresh cada hora
SELECT cron.schedule(
    'refresh-scanning-report',
    '0 * * * *', -- Cada hora en punto
    $$REFRESH MATERIALIZED VIEW CONCURRENTLY scanning_report_daily_full$$
);
*/

-- Alternativa: Refresh manual (ejecutar según necesidad)
-- REFRESH MATERIALIZED VIEW CONCURRENTLY scanning_report_daily_full;

-- =====================================================================
-- Paso 4: Analizar estadísticas para el optimizador de queries
-- =====================================================================
ANALYZE scanning_report_daily_full;

-- =====================================================================
-- Paso 5: Verificar que los índices se crearon correctamente
-- =====================================================================
SELECT
    indexname,
    indexdef
FROM pg_indexes
WHERE tablename = 'scanning_report_daily_full'
ORDER BY indexname;

-- =====================================================================
-- SCRIPT ALTERNATIVO: Si scanning_report_daily_full es una VISTA REGULAR
-- =====================================================================
/*
-- Si es una vista regular, necesitamos crear índices en las tablas base
-- Asumiendo que la vista consulta la tabla SplashWiFiScanningData:

-- Índice compuesto principal
CREATE INDEX IF NOT EXISTS idx_wifi_scanning_network_date
ON "SplashWiFiScanningData" ("NetworkId", "CreationTime" DESC);

-- Índice para filtros por fecha
CREATE INDEX IF NOT EXISTS idx_wifi_scanning_creation_time
ON "SplashWiFiScanningData" ("CreationTime" DESC);

-- Índice para MAC address
CREATE INDEX IF NOT EXISTS idx_wifi_scanning_mac
ON "SplashWiFiScanningData" ("ClientMac");

-- Índice para RSSI (usado en clasificación PasserBy/Visitor)
CREATE INDEX IF NOT EXISTS idx_wifi_scanning_rssi
ON "SplashWiFiScanningData" ("NearestApRssi");

-- Índice compuesto para queries complejas
CREATE INDEX IF NOT EXISTS idx_wifi_scanning_network_time_rssi
ON "SplashWiFiScanningData" ("NetworkId", "CreationTime" DESC, "NearestApRssi");

-- Analizar tabla base
ANALYZE "SplashWiFiScanningData";
*/

-- =====================================================================
-- Paso 6: Monitoreo de rendimiento (queries útiles)
-- =====================================================================

-- Ver tamaño de la vista/tabla
SELECT
    pg_size_pretty(pg_total_relation_size('scanning_report_daily_full')) as total_size,
    pg_size_pretty(pg_relation_size('scanning_report_daily_full')) as table_size,
    pg_size_pretty(pg_indexes_size('scanning_report_daily_full')) as indexes_size;

-- Ver queries lentas relacionadas con la vista (requiere pg_stat_statements)
/*
SELECT
    query,
    calls,
    total_exec_time,
    mean_exec_time,
    max_exec_time
FROM pg_stat_statements
WHERE query ILIKE '%scanning_report_daily_full%'
ORDER BY mean_exec_time DESC
LIMIT 10;
*/

-- =====================================================================
-- NOTAS IMPORTANTES
-- =====================================================================
/*
1. Si scanning_report_daily_full es una VISTA MATERIALIZADA:
   - Los índices mejoran las queries de lectura
   - Pero hacen más lento el REFRESH
   - Considerar refresh durante horas de bajo tráfico

2. Si es una VISTA REGULAR:
   - Usar el script alternativo para indexar tablas base
   - Los cambios se reflejan inmediatamente
   - No hay overhead de refresh

3. Monitoreo post-implementación:
   - Verificar plan de ejecución con EXPLAIN ANALYZE
   - Monitorear pg_stat_user_indexes para uso de índices
   - Ajustar según patrones de uso real

4. Mantenimiento:
   - REINDEX periódico si hay muchos UPDATEs/DELETEs
   - VACUUM ANALYZE regular
   - Considerar particionado si la tabla crece mucho (>10M rows)
*/

-- =====================================================================
-- FIN DEL SCRIPT
-- =====================================================================
