应根据字段类型和需求选择:需日期时间精度用NOW(),仅需日期部分用CURDATE();NOW()返回YYYY-MM-DD HH:MM:SS,CURDATE()返回YYYY-MM-DD,误用会导致类型不匹配或索引失效。

MySQL 中获取当前日期时间用 NOW() 还是 CURDATE()
要看你到底要什么:NOW() 返回完整的时间戳(年月日时分秒),CURDATE() 只返回日期部分(年月日)。如果查“当前日期和时间”,默认就是 NOW()。
常见错误是写成 SELECT NOW(漏了括号),会报错 FUNCTION database.NOW does not exist;或者误用 SYSDATE() —— 它和 NOW() 大多数情况结果一样,但 SYSDATE() 是执行时刻值,NOW() 是语句开始时刻值,在长事务或 SLEEP() 场景下可能不同。
-
NOW():适合大多数场景,一致性好 -
SYSDATE():需要精确到执行瞬间时才用 -
CURDATE()/CURTIME():只取日期或只取时间,别混着用
PostgreSQL 怎么写等价的当前时间查询
PostgreSQL 不认 NOW() 作为函数调用(虽然它支持 NOW 作为关键字),正确写法是 NOW() 加括号,或更推荐用 CURRENT_TIMESTAMP —— 后者是 SQL 标准写法,兼容性更好。
注意:CURRENT_DATE 和 CURRENT_TIME 分别对应日期和时间,但它们默认带时区(timestamp with time zone)。如果应用层不处理时区,容易出错。
- 推荐统一用
CURRENT_TIMESTAMP,语义清晰且跨数据库迁移成本低 - 避免用
clock_timestamp()除非你真需要函数内多次调用返回不同值 - 如果字段类型是
timestamp without time zone,显式 cast 更安全:CURRENT_TIMESTAMP::timestamp
SQLite 的 datetime('now') 为什么有时差
SQLite 没有原生日期类型,全靠字符串 + 函数模拟,datetime('now') 默认返回 UTC 时间。如果你所在时区不是 UTC,直接用会显示偏移。
解决办法是加修饰符:datetime('now', 'localtime')。但它依赖系统本地时区设置,部署在 Docker 或服务器上时,可能因容器未设 TZ 环境变量而回退到 UTC。
- 生产环境别依赖
localtime,优先在应用层做时区转换 - 测试时可用
datetime('now', '+8 hours')临时校准,但不可用于正式逻辑 -
strftime('%Y-%m-%d %H:%M:%S', 'now')能控制格式,但时区问题依旧存在
WHERE 条件里用 NOW() 会不会导致索引失效
会。比如 WHERE created_at > NOW() - INTERVAL 1 DAY,MySQL 无法用上 created_at 索引的范围扫描,因为 NOW() 是运行时计算值,优化器难以预估范围。
真正影响性能的是表达式是否可 SARGable(能利用索引)。把计算移到右边更安全:
WHERE created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)
但这只是写法优化,本质仍是函数调用。更稳的方式是应用层算好时间点传参:
WHERE created_at > ? -- 绑定 '2024-06-15 10:30:00'
- ORM 如 Django/SQLAlchemy 默认走参数绑定,天然规避这个问题
- 手写 SQL 时,能提前算就别让数据库现场算
-
NOW()本身很快,慢的是它破坏了索引选择性
时区、索引、函数行为差异——这三个点不提前确认,查出来的“当前时间”可能根本不是你要的那个“当前”。

















