-- V123: 删除 biz_file_result 上被复合索引完全覆盖的两个单列索引 -- -- 判定原则(同 V121):被删索引的列是另一索引的**严格前缀**, -- 所有能用它的查询都能被保留的复合索引覆盖,删除只减少写入侧的索引维护与 buffer pool 占用。 -- -- 1) biz_file_result.idx_task_id (task_id) -- 被 V38 的 idx_file_result_task_module_id (task_id, module_type, id) 覆盖。 -- 2) biz_file_result.idx_module_type (module_type) -- 被 V34 的 idx_biz_file_result_module_user_created (module_type, user_id, created_at) -- 与 V42 的 idx_file_result_patrol_history (module_type, user_id, created_at, id) 覆盖。 -- 两处均为 V1 建表时的遗留索引(当时还没有任何复合索引)。 -- -- 风险:DROP INDEX 为 INPLACE 在线操作,但会立即改变执行计划;两者均为「被覆盖」判定。 -- 回滚: -- ALTER TABLE biz_file_result ADD INDEX idx_task_id (task_id); -- ALTER TABLE biz_file_result ADD INDEX idx_module_type (module_type); SET @db_name = DATABASE(); -- 1) biz_file_result.idx_task_id SET @idx_exists := ( SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'biz_file_result' AND INDEX_NAME = 'idx_task_id' ); SET @sql := IF(@idx_exists > 0, 'ALTER TABLE biz_file_result DROP INDEX idx_task_id', 'SELECT 1' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- 2) biz_file_result.idx_module_type SET @idx_exists := ( SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'biz_file_result' AND INDEX_NAME = 'idx_module_type' ); SET @sql := IF(@idx_exists > 0, 'ALTER TABLE biz_file_result DROP INDEX idx_module_type', 'SELECT 1' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;