-- 优惠券状态管理优化SQL脚本 -- 作者: WebSoft -- 日期: 2025-01-15 -- 说明: 优化优惠券查询性能,添加必要的索引 -- ======================================== -- 1. 添加索引优化查询性能 -- ======================================== -- 用户优惠券表索引优化 CREATE INDEX IF NOT EXISTS idx_user_coupon_status ON shop_user_coupon(user_id, status, expire_time); CREATE INDEX IF NOT EXISTS idx_user_coupon_expire ON shop_user_coupon(expire_time) WHERE status = 0; CREATE INDEX IF NOT EXISTS idx_user_coupon_order ON shop_user_coupon(order_id) WHERE status = 1; -- 优惠券模板表索引优化 CREATE INDEX IF NOT EXISTS idx_coupon_status_expire ON shop_coupon(status, expire_type, end_time); -- ======================================== -- 2. 统一状态字段(如果需要数据迁移) -- ======================================== -- 检查现有数据的状态一致性 SELECT '状态一致性检查' as check_item, COUNT(*) as total_count, SUM(CASE WHEN status = 0 AND is_use = 0 AND is_expire = 0 THEN 1 ELSE 0 END) as available_count, SUM(CASE WHEN status = 1 AND is_use = 1 THEN 1 ELSE 0 END) as used_count, SUM(CASE WHEN status = 2 OR is_expire = 1 THEN 1 ELSE 0 END) as expired_count, SUM(CASE WHEN (status = 0 AND (is_use = 1 OR is_expire = 1)) OR (status = 1 AND is_use = 0) OR (status = 2 AND is_expire = 0) THEN 1 ELSE 0 END) as inconsistent_count FROM shop_user_coupon; -- 修复状态不一致的数据 UPDATE shop_user_coupon SET status = 1, is_use = 1 WHERE status = 0 AND is_use = 1 AND is_expire = 0; UPDATE shop_user_coupon SET status = 2, is_expire = 1 WHERE status = 0 AND is_expire = 1; UPDATE shop_user_coupon SET status = 2, is_expire = 1 WHERE status IN (0, 1) AND end_time < NOW(); -- ======================================== -- 3. 添加触发器自动更新过期状态(可选) -- ======================================== DELIMITER $$ -- 创建触发器:在查询时自动检查过期状态 CREATE TRIGGER IF NOT EXISTS tr_check_coupon_expire BEFORE UPDATE ON shop_user_coupon FOR EACH ROW BEGIN -- 如果是未使用状态且已过期,自动更新为过期状态 IF NEW.status = 0 AND NEW.end_time < NOW() THEN SET NEW.status = 2; SET NEW.is_expire = 1; END IF; END$$ DELIMITER ; -- ======================================== -- 4. 创建视图简化查询 -- ======================================== -- 创建用户可用优惠券视图 CREATE OR REPLACE VIEW v_user_available_coupons AS SELECT uc.*, c.name as coupon_name, c.description as coupon_description, c.apply_range, c.apply_range_config, CASE WHEN uc.end_time < NOW() THEN '已过期' WHEN uc.status = 1 THEN '已使用' WHEN uc.status = 0 THEN '可使用' ELSE '未知状态' END as status_desc FROM shop_user_coupon uc LEFT JOIN shop_coupon c ON uc.coupon_id = c.id WHERE uc.deleted = 0; -- 创建优惠券统计视图 CREATE OR REPLACE VIEW v_coupon_statistics AS SELECT user_id, COUNT(*) as total_count, SUM(CASE WHEN status = 0 AND end_time >= NOW() THEN 1 ELSE 0 END) as available_count, SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count, SUM(CASE WHEN status = 2 OR end_time < NOW() THEN 1 ELSE 0 END) as expired_count FROM shop_user_coupon WHERE deleted = 0 GROUP BY user_id; -- ======================================== -- 5. 存储过程:批量处理过期优惠券 -- ======================================== DELIMITER $$ CREATE PROCEDURE IF NOT EXISTS sp_update_expired_coupons() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE update_count INT DEFAULT 0; -- 声明异常处理 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; RESIGNAL; END; START TRANSACTION; -- 批量更新过期优惠券 UPDATE shop_user_coupon SET status = 2, is_expire = 1 WHERE status = 0 AND end_time < NOW() AND deleted = 0; -- 获取更新数量 SET update_count = ROW_COUNT(); COMMIT; -- 返回更新数量 SELECT update_count as updated_count; END$$ DELIMITER ; -- ======================================== -- 6. 性能监控查询 -- ======================================== -- 查看优惠券状态分布 SELECT status, CASE WHEN status = 0 THEN '未使用' WHEN status = 1 THEN '已使用' WHEN status = 2 THEN '已过期' ELSE '未知' END as status_name, COUNT(*) as count, ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM shop_user_coupon WHERE deleted = 0), 2) as percentage FROM shop_user_coupon WHERE deleted = 0 GROUP BY status ORDER BY status; -- 查看即将过期的优惠券(7天内) SELECT COUNT(*) as expiring_soon_count, MIN(end_time) as earliest_expire_time, MAX(end_time) as latest_expire_time FROM shop_user_coupon WHERE status = 0 AND end_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY) AND deleted = 0; -- 查看优惠券使用率统计 SELECT DATE(create_time) as date, COUNT(*) as issued_count, SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count, ROUND(SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as usage_rate FROM shop_user_coupon WHERE deleted = 0 AND create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY) GROUP BY DATE(create_time) ORDER BY date DESC; -- ======================================== -- 7. 清理和维护 -- ======================================== -- 清理过期很久的优惠券记录(可选,谨慎使用) -- DELETE FROM shop_user_coupon -- WHERE status = 2 -- AND end_time < DATE_SUB(NOW(), INTERVAL 1 YEAR) -- AND deleted = 0; COMMIT;