-- S8-NOTIFICATION-LOG-INDEX-DDL-P2-3
-- Target table: ado_s8_notification_log
-- Purpose: 仅用于 S8 notification_log 索引硬化，覆盖以下查询路径：
--   A. (channel, created_at) → stuck/orphan dedup 60min cooldown
--      query (S8ActiveFlowWatchService.cs 行 67-70 / 175-178)。
--   B. (created_at)          → P1.2 S8LogRetentionCleanupJob 的
--      created_at < cutoff 批量清理。
--
-- 设计边界：
--   1. 仅新增 2 个二级索引，不改变任何数据；
--   2. 不改字段、不改字段类型、不改 nullable、不改表结构；
--   3. 不执行 DML（INSERT/UPDATE/DELETE）；
--   4. 不执行 DROP TABLE / TRUNCATE / ALTER COLUMN / MODIFY COLUMN；
--   5. 执行前必须先跑下方 pre-check SELECT，命中（>0 行）即跳过对应 CREATE INDEX；
--   6. 索引名必须与 AdoS8NotificationLog 实体 [SugarIndex] 注解完全一致：
--        - idx_s8_notif_channel_time (Channel, CreatedAt)
--        - idx_s8_notif_created_at   (CreatedAt)
--      避免 EnableInitTable=true 时 CodeFirst 与手工 DDL 冲突；
--   7. 使用 ALGORITHM=INPLACE, LOCK=NONE，与 InnoDB ONLINE DDL 一致，
--      避免对在线写入产生表锁；
--   8. 建议低峰执行；执行时机由数据负责人在阶段 2 决定。
--
-- 不在本脚本范围：
--   - 暂不包含 (tenant_id, factory_id, channel, created_at) 复合索引（候选 C，
--     留待后续聚合/API 瓶颈出现后再评估）；
--   - 不在 ado_s8_notification_log 上做任何 DROP；如需回滚，请使用同目录的
--     20260531_s8_notification_log_indexes_rollback.sql。
--
-- Idempotency:
--   MySQL 8 不支持 CREATE INDEX IF NOT EXISTS。如果索引已存在重跑会抛
--   "Duplicate key name"，属安全错误，先跑 pre-check 可避免。

-- =========================================================================
-- Pre-check (run first; non-destructive; expect 0 rows when index absent)
-- =========================================================================

-- Pre-check A: idx_s8_notif_channel_time
SELECT COUNT(*) AS exists_channel_time
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = 'ado_s8_notification_log'
  AND INDEX_NAME = 'idx_s8_notif_channel_time';

-- Pre-check B: idx_s8_notif_created_at
SELECT COUNT(*) AS exists_created_at
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = 'ado_s8_notification_log'
  AND INDEX_NAME = 'idx_s8_notif_created_at';

-- =========================================================================
-- Index creation (run each only when its pre-check returned 0)
-- =========================================================================

-- Index A: stuck/orphan dedup 60min cooldown (channel + created_at)
CREATE INDEX idx_s8_notif_channel_time
ON ado_s8_notification_log (channel, created_at)
ALGORITHM=INPLACE LOCK=NONE;

-- Index B: retention cleanup (created_at < cutoff)
CREATE INDEX idx_s8_notif_created_at
ON ado_s8_notification_log (created_at)
ALGORITHM=INPLACE LOCK=NONE;

-- =========================================================================
-- Post-check (run after creation; expect 2 rows total, one per index)
-- =========================================================================

SELECT INDEX_NAME, GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) AS cols
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = 'ado_s8_notification_log'
  AND INDEX_NAME IN (
    'idx_s8_notif_channel_time',
    'idx_s8_notif_created_at'
  )
GROUP BY INDEX_NAME;
