Mysql
當我們在時間戳和日期時間之間取時間差異時會發生什麼
假設我在 mysql (5.5+) 中有下表:
CREATE TABLE IF NOT EXISTS `test` ( `id` int(11) NOT NULL, `x_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `y_time` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
我的 x_time 是 a
timestamp
,而 y_time 是一datetime
列我想了解當我這樣做時會發生什麼
TIMESTAMPDIFF(SECOND, x_time, y_time)
是否
x_time
轉換為datetime
然後計算差異?或者反之亦然?Mysql 手冊(http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_timestampdiff)說:一個表達式可能是日期,另一個是日期時間;日期值在必要時被視為具有時間部分“00:00:00”的日期時間。我的假設是兩個列
x_time
都y_time
必須是一種數據類型才能計算 TIMESTAMPDIFF,如果還沒有,那麼 mysql 必須在內部進行。我在這裡錯了嗎?此外,如果它必須轉換其中一列以匹配另一列的數據類型,那麼性能對以下查詢有何影響?它會為 5000 行進行數據類型轉換嗎?這是多麼耗時的過程?
SELECT * from test WHERE `TIMESTAMPDIFF(SECOND, x_time, y_time)` LIMIT 100000, 5000
除了 Rolando 的回答,請注意
TIMESTAMP
列是時區感知的,而DATETIME
不是。如果您沒有多個時區,那麼您可以;但是,如果您想轉換到其他時區,
TIMESTAMPDIFF
計算將提供損壞的結果。
由於查詢的評估方式,您基本上會讓 mysql 發瘋。
再看查詢
SELECT * from test WHERE `TIMESTAMPDIFF(SECOND, x_time, y_time)` LIMIT 100000, 5000
請注意在呈現任何數據之前查詢將做什麼
- 您將進行全表掃描
- 您實際上是在每一行上執行數據減法
- 您將所有滿足查詢的行收集到一個臨時表中
- 您將跳過臨時表中的 100,000 行
- 此後您將檢索 5,000
索引兩列將無濟於事。為什麼 ?因為需要日期減法,所以不需要索引。在這種情況下,內部轉換為一種或另一種日期類型是您最不擔心的。
建議
儲存時差並建立索引
ALTER TABLE test ADD timediffsec INT DEFAULT 0; UPDATE test SET timediffsec = UNIX_TIMESTAMP(x_time) - UNIX_TIMESTAMP(y_time); ALTER TABLE test ADD INDEX (timediffsec);
現在您可以像這樣查詢:
SELECT * from test WHERE timediffsec > 0 LIMIT 100000, 5000
檢查已經計算的時間差比為每一行計算時間差更能提高性能。
試一試 !!!