NOW()在语句开始时快照时间,值稳定;SYSDATE()每次调用实时获取系统时间,可能因执行延迟产生差异;推荐多数场景用NOW(),仅特殊需求才用SYSDATE()。

NOW() 和 SYSDATE() 返回值看起来一样,但执行时机不同
它们都返回 NOW() 和 SYSDATE() 都返回当前日期时间(格式为 'YYYY-MM-DD HH:MM:SS'),但关键区别在于:前者在语句开始执行时“快照”一次时间,后者每次调用都实时获取系统时间。这在复杂语句里会暴露差异。
比如在一条 UPDATE 语句中多次调用,NOW() 总是相同值,而 SYSDATE() 可能因执行延迟产生微小差异(尤其在慢查询或高负载下)。
在 INSERT 或 UPDATE 中用哪个更安全
绝大多数场景推荐用 NOW()。它行为稳定、可预测,且与事务时间点对齐——同一事务中所有 NOW() 调用结果一致,适合记录“操作发生时刻”。
-
SYSDATE()在存储过程或触发器中若含耗时逻辑(如循环、子查询),可能导致字段写入时间不一致 - 复制环境下,基于语句的复制(SBR)要求函数行为确定,
SYSDATE()被视为“非确定性函数”,可能触发警告甚至失败 - 如果明确需要记录某一行“实际写入磁盘的时刻”,才考虑
SYSDATE(),但这种情况极少
如何验证两者差异
用一条带 SLEEP() 的 SELECT 最直观:
SELECT NOW(), SLEEP(2), NOW(), SYSDATE(), SLEEP(2), SYSDATE();
结果中前两个 NOW() 值相同;两个 SYSDATE() 值相差约 2 秒;中间那个 SYSDATE() 是第一个 SLEEP() 后立即取的,也和前一个不同。
注意:SLEEP() 是阻塞函数,别在生产环境乱用;这只是验证手段。
替代方案:UTC 时间与精度问题
如果业务需跨时区一致性,别依赖 NOW() 或 SYSDATE(),它们都返回服务器本地时区时间。改用:
-
UTC_TIMESTAMP()—— 返回 UTC 时间,行为类似NOW()(语句开始快照) -
SYSDATE(6)或NOW(6)—— 支持微秒精度(MySQL 5.6.4+),括号内数字表示小数位数 - 避免用
CURRENT_TIMESTAMP当函数调用,它只是NOW()的同义词,无额外特性
微秒精度在日志排序、高频写入场景有用,但要注意客户端驱动和应用层是否真正支持解析。


















