在本教學中,您將了解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之前應該考慮的一些原因。