摘要:在本教程中,您将了解 MySQL SYSDATE()
函数及其注意事项。
MySQL SYSDATE
函数简介
下面说明了SYSDATE()
函数的语法:
SYSDATE(fsp);
Code language: SQL (Structured Query Language) (sql)
如果在字符串上下文中使用SYSDATE()
函数,则以'YYYY-MM-DD HH:MM:SS'
格式返回当前日期和时间;如果在数字上下文中使用函数,则以YYYYMMDDHHMMSS
格式返回当前日期和时间。 。
SYSDATE()
函数接受一个可选参数fsp
,该参数确定结果是否应包含秒精度(范围从 0 到 6)。
请参阅以下示例。
mysql> SELECT SYSDATE();
+---------------------+
| SYSDATE() |
+---------------------+
| 2017-07-13 17:42:37 |
+---------------------+
1 row in set (0.00 sec)
Code language: SQL (Structured Query Language) (sql)
如果传递fsp
参数,结果将包括秒小数精度,如下例所示:
mysql> SELECT SYSDATE(3);
+-------------------------+
| SYSDATE(3) |
+-------------------------+
| 2017-07-13 17:42:55.875 |
+-------------------------+
1 row in set (0.00 sec)
Code language: SQL (Structured Query Language) (sql)
系统日期与现在
考虑以下示例。
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)
Code language: SQL (Structured Query Language) (sql)
看来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)
Code language: SQL (Structured Query Language) (sql)
在此示例中,我们使用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)
Code language: SQL (Structured Query Language) (sql)
在同一语句中, 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;
Code language: SQL (Structured Query Language) (sql)
请注意,我们使用递归 CTE来生成时间序列。 CTE 自 MySQL 8.0 起可用
由于t
列具有唯一索引,因此以下查询应该执行得很快:
SELECT
id,
t
FROM
tests
WHERE
t >= SYSDATE() - INTERVAL 1 DAY;
Code language: SQL (Structured Query Language) (sql)
然而,完成需要 15 毫秒。让我们使用EXPLAIN
语句查看详细信息。
EXPLAIN SELECT
id, t
FROM
tests
WHERE
t >= SYSDATE() - INTERVAL 1 DAY;
Code language: SQL (Structured Query Language) (sql)
事实证明,MySQL 必须扫描表中的所有行才能获取数据。该索引无法使用。
如果将查询中的SYSDATE()
更改为NOW()
函数:
SELECT
id,
t
FROM
tests
WHERE
t >= NOW() - INTERVAL 1 DAY;
Code language: SQL (Structured Query Language) (sql)
使用NOW()
函数,索引已用于查询数据,如下面的EXPLAIN
结果所示:
EXPLAIN SELECT
id,
t
FROM
tests
WHERE
t >= NOW() - INTERVAL 1 DAY;
Code language: SQL (Structured Query Language) (sql)
--sysdate-is-now
选项,可以使SYSDATE()
函数的行为与NOW()
函数相同。在本教程中,您了解了 MySQL SYSDATE()
函数以及在使用它之前应三思而后行的原因。