转载自 MySQL sysdate()函数
下面说明了SYSDATE()
函数的语法:
SYSDATE(fsp);
如果函数用于字符串上下文或YYYYMMDDHHMMSS
格式,则SYSDATE()
函数将返回当前日期时间,格式为“YYYY-MM-DD HH:MM:SS”
的值,以防在函数用于数字上下文。
SYSDATE()
函数接受一个可选参数fsp
,它确定结果是否应该包含从0
到6
的小数秒精度。
请参见以下示例 -
mysql> SELECT SYSDATE();
+---------------------+
| SYSDATE() |
+---------------------+
| 2017-08-10 20:43:16 |
+---------------------+
1 row in set
如果您传递fsp
参数,则结果将包括小数秒精度,如以下示例所示:
mysql> SELECT SYSDATE(3);
+-------------------------+
| SYSDATE(3) |
+-------------------------+
| 2017-08-10 20:43:46.985 |
+-------------------------+
1 row in set
请考虑以下示例 -
mysql> SELECT SYSDATE(), NOW();
+---------------------+---------------------+
| SYSDATE() | NOW() |
+---------------------+---------------------+
| 2017-08-10 20:44:38 | 2017-08-10 20:44:38 |
+---------------------+---------------------+
1 row in set
似乎SYSDATE()
和NOW()函数都返回一个相同的值,它是执行语句时当前日期和时间。
然而,SYSDATE()
函数实际上返回执行时的时间,而NOW()
函数返回一个常量时间,该语句开始执行。
请参阅以下查询:
mysql> SELECT NOW(), SLEEP(5), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(5) | NOW() |
+---------------------+----------+---------------------+
| 2017-08-10 20:46:51 | 0 | 2017-08-10 20:46:51 |
+---------------------+----------+---------------------+
1 row in set
在这个例子中,我们使用SLEEP()
函数暂停查询5
秒。 在同一个语句中,NOW()
函数总是返回一个常量,它是语句开始的时间。
我们将NOW()
函数更改为SYSDATE()
函数:
mysql> SELECT SYSDATE(), SLEEP(5), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(5) | SYSDATE() |
+---------------------+----------+---------------------+
| 2017-08-10 20:48:14 | 0 | 2017-08-10 20:48:19 |
+---------------------+----------+---------------------+
1 row in set
在同一个语句中,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来生成时间序列。 CTE从MySQL 8.0开始才有的功能。
因为t
列有唯一索引,所以下列查询应该执行得很快:
SELECT
id,
t
FROM
tests
WHERE
t >= SYSDATE() - INTERVAL 1 DAY;
但是,需要15ms
才能完成。让我们使用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()
函数以及在使用MySQL之前应该考虑的一些原因。