Mysql

當我們在時間戳和日期時間之間取時間差異時會發生什麼

  • June 15, 2014

假設我在 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_timey_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

檢查已經計算的時間差比為每一行計算時間差更能提高性能。

試一試 !!!

引用自:https://dba.stackexchange.com/questions/56671