首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 實現定時/延時執行:利用 SLEEP() 與 TIMESTAMPDIFF() 模擬 SQL Server WAITFOR

     編輯:MySQL 綜合教學

MySQL 無原生 WAITFOR DELAY/TIME,但可通過 SLEEP(秒數) 配合時間差計算實現同等效果,適用於測試驗證、簡易排程場景。

一、SLEEP() 基礎行為

SELECT SLEEP(1), id FROM t;  -- 每行睡 1 秒,N 行總耗時 N 秒

關鍵點:SLEEP 在每行執行時阻塞,非語句級一次性等待。

二、延時執行(WAITFOR DELAY 等效)

-- 等待 1 秒後查詢
SELECT SLEEP(1);
SELECT * FROM t;

或單語句塊(需 DELIMITER):

DELIMITER //
SELECT SLEEP(1);
SELECT * FROM t;//
DELIMITER ;

三、定時執行(WAITFOR TIME 等效)

核心: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、跨庫操作

六、Event Scheduler 快速上手

-- 啟用
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 會長時間持有鎖,極易引發阻塞,嚴禁在事務中使用。
  • 動態 SQL 需防注入,僅信任內部調用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved