| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- -- 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;
|