MySQL SYSDATE函数
简介:在本教程中,您将了解MySQL SYSDATE()函数及其警告。
MySQL SYSDATE函数简介
下面说明了SYSDATE()函数的语法:
SYSDATE(fsp);
如果该函数用于字符串上下文或YYYYMMDDHHMMSS格式,则SYSDATE()函数以'YYYY-MM-DD HH:MM:SS'格式返回当前日期和时间作为值,如果该函数用于数字上下文。
SYSDATE()函数接受一个可选参数fsp,该参数确定结果是否应包括从0到6的小数秒精度。
请参见以下示例。
mysql> SELECT SYSDATE(); +---------------------+ | SYSDATE() | +---------------------+ | 2017-07-13 17:42:37 | +---------------------+ 1 row in set (0.00 sec)
如果传递fsp参数,结果将包括小数秒精度,如以下示例所示:
mysql> SELECT SYSDATE(3); +-------------------------+ | SYSDATE(3) | +-------------------------+ | 2017-07-13 17:42:55.875 | +-------------------------+ 1 row in set (0.00 sec)
SYSDATE与现在
考虑以下示例。
mysql> SELECT SYSDATE(), NOW(); +---------------------+---------------------+ | SYSDATE() | NOW() | +---------------------+---------------------+ | 2017-07-13 17:46:30 | 2017-07-13 17:46:30 | +---------------------+---------------------+ 1 row in set (0.00 sec)
似乎SYSDATE()和NOW()函数都返回相同的值,该值是执行它的当前日期和时间。
但是,SYSDATE()函数实际上返回执行时间,而NOW()函数返回恒定时间开始执行语句。
请参阅以下查询:
mysql> SELECT NOW(), SLEEP(5), NOW(); +---------------------+----------+---------------------+ | NOW() | SLEEP(5) | NOW() | +---------------------+----------+---------------------+ | 2017-07-13 17:49:18 | 0 | 2017-07-13 17:49:18 | +---------------------+----------+---------------------+ 1 row in set (5.00 sec)
在此示例中,我们使用SLEEP()函数将查询暂停了5秒钟。
在同一条语句中,NOW()函数始终返回一个常量,该常量是该语句开始的时间。
让我们将NOW()函数更改为SYSDATE()函数:
mysql> SELECT SYSDATE(), SLEEP(5), SYSDATE(); +---------------------+----------+---------------------+ | SYSDATE() | SLEEP(5) | SYSDATE() | +---------------------+----------+---------------------+ | 2017-07-13 17:50:57 | 0 | 2017-07-13 17:51:02 | +---------------------+----------+---------------------+ 1 row in set (5.00 sec)
在同一条语句中,SYSDATE()函数返回不同的时间值,这些时间值反映了SYSDATE()函数的执行时间。
因为SYSDATE()函数是不确定的,所以不能使用索引来评估引用该函数的表达式。
为了说明这一点,我们将创建一个名为tests的表,并将一些数据插入该表中。
CREATE TABLE tests ( id INT AUTO_INCREMENT PRIMARY KEY, t DATETIME UNIQUE ); INSERT INTO tests(t) WITH RECURSIVE times(t) AS ( SELECT now() - interval 1 YEAR t UNION ALL SELECT t + interval 1 hour FROM times WHERE t < now() ) SELECT t FROM times;
请注意,我们使用了递归CTE来生成时间序列。
自MySQL 8.0以来,CTE已可用
由于t列具有唯一索引,因此以下查询应快速执行:
SELECT id, t FROM tests WHERE t >= SYSDATE() - INTERVAL 1 DAY;
但是,它需要15毫秒才能完成。
让我们使用EXPLAIN语句查看详细信息。
EXPLAIN SELECT id, t FROM tests WHERE t >= SYSDATE() - INTERVAL 1 DAY;
事实证明,MySQL必须扫描表中的所有行以获取数据。
该索引无法使用。
如果在查询中将SYSDATE()更改为NOW()函数:
SELECT id, t FROM tests WHERE t >= NOW() - INTERVAL 1 DAY;
借助NOW()函数,索引已用于查询数据,如下面的EXPLAIN结果所示:
EXPLAIN SELECT id, t FROM tests WHERE t >= NOW() - INTERVAL 1 DAY;
请注意,MySQL为您提供了--sysdate-is-now选项,可以使SYSDATE()函数的行为与NOW()函数相同。
在本教程中,您了解了MySQL SYSDATE()函数以及为什么在使用它之前应该三思而后行的原因。