性能与精度之争:深入对比 MySQL 中 NOW() 和 SYSDATE() 的异同及影响

时间:2025-09-20 18:21

       在 MySQL 中获取当前日期和时间是非常常见的操作,主要用于数据记录、时间计算和过滤等场景。MySQL 提供了一系列函数来满足不同的精度和格式需求。

以下是几种最核心和常用的方法。

一、 核心函数概述

MySQL 提供了多个函数来获取当前时间,区别在于返回值的格式和精度:

| 函数 | 返回格式 | 描述 | 示例输出 |

| : | : | : | : |

| ​​NOW()​​​ | ​​YYYY-MM-DD HH:MM:SS​​​ | 返回当前的日期和时间(会话时区)。 | ​​2023-10-27 14:32:05​​ |

| ​​CURRENT_TIMESTAMP()​​​ | ​​YYYY-MM-DD HH:MM:SS​​​ | ​​NOW()​​​ 的同义词,功能完全相同。 | ​​2023-10-27 14:32:05​​ |

| ​​CURDATE()​​​ | ​​YYYY-MM-DD​​​ | 返回当前的日期。 | ​​2023-10-27​​ |

| ​​CURRENT_DATE()​​​ | ​​YYYY-MM-DD​​​ | ​​CURDATE()​​​ 的同义词。 | ​​2023-10-27​​ |

| ​​CURTIME()​​​ | ​​HH:MM:SS​​​ | 返回当前的时间。 | ​​14:32:05​​ |

| ​​CURRENT_TIME()​​​ | ​​HH:MM:SS​​​ | ​​CURTIME()​​​ 的同义词。 | ​​14:32:05​​ |

| ​​SYSDATE()​​​ | ​​YYYY-MM-DD HH:MM:SS​​​ | 返回函数执行时的日期时间。 | ​​2023-10-27 14:32:05​​ |

| ​​UTC_DATE()​​​ | ​​YYYY-MM-DD​​​ | 返回当前的 UTC 日期。 | ​​2023-10-27​​ |

| ​​UTC_TIME()​​​ | ​​HH:MM:SS​​​ | 返回当前的 UTC 时间。 | ​​06:32:05​​ |

| ​​UTC_TIMESTAMP()​​​ | ​​YYYY-MM-DD HH:MM:SS​​​ | 返回当前的 UTC 日期和时间。 | ​​2023-10-27 06:32:05​​ |

二、 详细说明与示例

  1. 获取完整的日期和时间 (​​NOW()​​​ vs ​​SYSDATE()​​)

​NOW()​​​ 返回语句开始执行时的时间。在一个 SQL 语句中,无论 ​​NOW()​​ 被调用多少次,它返回的值都是相同的。

​SYSDATE()​​​ 返回该函数被执行时的精确时间。这意味着在一个语句中多次调用 ​​SYSDATE()​​ 会得到不同的值。

示例:

SELECT NOW(), SLEEP(2), NOW();

-- 结果:两个 NOW() 返回的时间完全相同,即使查询中间睡眠了2秒。

-- | NOW()               | SLEEP(2) | NOW()               |

-- ||-||

-- | 2023-10-27 14:35:01 |        0 | 2023-10-27 14:35:01 |



SELECT SYSDATE(), SLEEP(2), SYSDATE();

-- 结果:两个 SYSDATE() 返回的时间相差2秒。

-- | SYSDATE()           | SLEEP(2) | SYSDATE()           |

-- ||-||

-- | 2023-10-27 14:35:03 |        0 | 2023-10-27 14:35:05 |

注意: 由于 ​​SYSDATE()​​​ 的行为可能对复制(Replication)和确定性查询造成意想不到的影响,通常建议优先使用 ​​NOW()​​。

  1. 获取日期或时间的部分

如果你只需要当前日期或当前时间,可以使用相应的函数。

示例:

-- 插入一条记录,自动记录创建日期和时间

INSERT INTO orders (product_id, quantity, created_at)

VALUES (101, 2, NOW());



-- 查询今天的所有订单

SELECT FROM orders WHERE DATE(created_at) = CURDATE();



-- 查询所有在下午2点之后创建的订单

SELECT FROM orders WHERE TIME(created_at) > '14:00:00';
  1. 获取 UNIX 时间戳

​UNIX_TIMESTAMP()​​ 函数通常用于获取一个 UNIX 时间戳(自 '1970-01-01 00:00:00' UTC 以来的秒数)。

如果不带参数调用,它返回当前的 UNIX 时间戳。

如果带一个日期时间参数,它返回该日期时间对应的 UNIX 时间戳。

示例:

SELECT UNIX_TIMESTAMP(); -- 输出类似:1698411725

SELECT UNIX_TIMESTAMP('2023-10-27 14:32:05'); -- 将指定时间转换为时间戳

三、 高级用法:时区的影响

时间函数返回的值取决于 MySQL 的时区设置。

​NOW()​​​, ​​CURDATE()​​ 等函数返回的是当前会话时区的时间。

​UTC_DATE()​​​, ​​UTC_TIMESTAMP()​​ 等函数返回的是 UTC 时间。

你可以查看和设置会话时区:

-- 查看当前时区设置

SELECT @@system_time_zone, @@session.time_zone;



-- 设置当前会话的时区(例如,设置为东八区 - 北京时间)

SET SESSION time_zone = '+08:00';

示例:

假设 MySQL 服务器位于伦敦(UTC时区),而你的会话时区设置为北京时间(UTC+8)。

SET SESSION time_zone = '+08:00';

SELECT NOW(), UTC_TIMESTAMP(), UNIX_TIMESTAMP();

输出可能会是:

++++

| NOW()               | UTC_TIMESTAMP()     | UNIX_TIMESTAMP()    |

++++

| 2023-10-27 22:00:00 | 2023-10-27 14:00:00 |         1698415200  |

++++

​UNIX_TIMESTAMP()​​ 不受时区设置影响,它总是基于 UTC。

总结与最佳实践

  1. 常用选择:
    记录数据创建/更新时间:在表结构设计中,通常使用 ​​​TIMESTAMP​​​ 或 ​​DATETIME​​​ 类型的字段,并将其默认值设置为 ​​CURRENT_TIMESTAMP​​​(等同于 ​​NOW()​​​)。
    获取当前时间:优先使用 ​​​NOW()​​​,而不是 ​​SYSDATE()​​​,除非你有特殊需求。
    只需要日期或时间部分:使用 ​​​CURDATE()​​​ 或 ​​CURTIME()​​。
  2. 时区意识:
    如果你的应用是国际化的,务必注意时区问题。在存储时间时,可以考虑使用 UTC 时间(​​​UTC_TIMESTAMP()​​)并在应用层根据用户所在地进行转换,或者确保会话时区设置正确。
  3. 表结构设计示例:
CREATE TABLE logs (

    id INT AUTO_INCREMENT PRIMARY KEY,

    message TEXT,

    -- 设置默认值,在插入时自动写入当前时间

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

    -- 使用 DATETIME 类型也可以,但语法略有不同

    updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP

);

另外搭配便捷的MYSQL备份工具,可定时备份、异地备份,MYSQL导出导入。可本地连接LINUX里的MYSQL,简单便捷。可以大大地提高工作效率喔。

MySQL处理中文排序,除了拼音还能怎么办?一文掌握拼音与笔画排序的所有奥秘
一小时速通MySQL:零基础入门到精通,看这篇就够了(下篇)
一小时速通MySQL:零基础入门到精通,看这篇就够了(上篇)
MySQL小白下载指南 (以 Windows 为例)
MySQL安装太难?看完这篇就够了!小白专属下载安装指南
MySQL清空表数据,你用DELETE还是TRUNCATE?一文讲清两者核心差异与正确使用场景
从查询崩溃到丝滑流畅:详解MySQL性能优化的核心路径与高频实战技巧
MySQL性能优化漫谈:从金字塔法则到避坑指南,一位老DBA的架构思维与实践总结
千万级数据何去何从?一文读懂MySQL分库分表面试与工程实践的核心要点
mysql2,用于与 MySQL 数据库进行交互