MySQL sysdate()函數

在本教學中,您將瞭解MySQL SYSDATE()函數及其注意事項。

MySQL SYSDATE函數介紹

下麵說明了SYSDATE()函數的語法:

SYSDATE(fsp);

如果函數用於字串上下文或YYYYMMDDHHMMSS格式,則SYSDATE()函數將返回當前日期時間,格式為“YYYY-MM-DD HH:MM:SS”的值,以防在函數用於數字上下文。

SYSDATE()函數接受一個可選參數fsp,它確定結果是否應該包含從06的小數秒精度。

請參見以下示例 -

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

SYSDATE 與 NOW 比較

請考慮以下示例 -

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之前應該考慮的一些原因。


上一篇: MySQL函數 下一篇: MySQL+Node.js連接和操作