MySQL 無原生 WAITFOR DELAY/TIME,但可通過 SLEEP(秒數) 配合時間差計算實現同等效果,適用於測試驗證、簡易排程場景。
SELECT SLEEP(1), id FROM t; -- 每行睡 1 秒,N 行總耗時 N 秒
關鍵點:SLEEP 在每行執行時阻塞,非語句級一次性等待。
-- 等待 1 秒後查詢 SELECT SLEEP(1); SELECT * FROM t;
或單語句塊(需 DELIMITER):
DELIMITER // SELECT SLEEP(1); SELECT * FROM t;// DELIMITER ;
核心:TIMESTAMPDIFF(SECOND, NOW(), 目標時間) 計算需等待秒數。
SET @target = '2023-12-01 15:30:00'; SET @wait_sec = TIMESTAMPDIFF(SECOND, NOW(), @target); SELECT SLEEP(@wait_sec); SELECT NOW(); -- 驗證到達時間 SELECT * FROM t; -- 目標業務 SQL
DELIMITER //
CREATE PROCEDURE exec_at_target(IN target_dt DATETIME, IN biz_sql TEXT)
BEGIN
DECLARE wait_sec BIGINT;
SET wait_sec = TIMESTAMPDIFF(SECOND, NOW(), target_dt);
IF wait_sec > 0 THEN
SELECT SLEEP(wait_sec);
END IF;
-- 動態執行業務 SQL(需 PREPARE)
SET @sql = biz_sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END//
DELIMITER ;
-- 調用示例
CALL exec_at_target('2023-12-01 15:30:00', 'INSERT INTO log(msg) VALUES("scheduled")');
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| SLEEP + 時間差 | 無額外對象、臨時測試便捷 | 佔用連接、長等待易超時、無持久化/重試/監控 | 開發調試、一次性腳本 |
| Event Scheduler | 原生、持久化、支持循環、SHOW EVENTS 可視 | 需啟用 event_scheduler=ON、精度秒級 | 定期維護、統計聚合、數據歸檔 |
| 系統定時任務 | 獨立於 DB、語言無關、成熟監控 | 需外部依賴、分佈式需鎖協調 | 生產級排程、ETL、跨庫操作 |
-- 啟用 SET GLOBAL event_scheduler = ON; -- 永久生效加入 my.cnf: event_scheduler=ON -- 建立每日 02:00 執行 CREATE EVENT daily_cleanup ON SCHEDULE EVERY 1 DAY STARTS '2023-01-01 02:00:00' DO DELETE FROM tmp_log WHERE create_time < DATE_SUB(NOW(), INTERVAL 7 DAY); -- 查看/管理 SHOW EVENTS; ALTER EVENT daily_cleanup DISABLE; DROP EVENT daily_cleanup;
SLEEP 最大值 2147483647 秒(約 68 年),負數報錯。SLEEP 會佔用連接槽位,受 wait_timeout/max_execution_time 限制。SLEEP 會長時間持有鎖,極易引發阻塞,嚴禁在事務中使用。