检查时间戳/日期时间是否属于指定日期的最佳方法是哪种方法

时间:2009-11-07 00:37:29

标签: mysql database datetime date timestamp

有时我在数据库中有一个日期时间或时间戳列,例如,我需要选择今天更新时间戳的所有记录。

我通常这样做:

SELECT * FROM mytable WHERE CAST(TS AS DATE) = CURDATE();  
SELECT * FROM mytable WHERE CAST(TS AS DATE) = '2009-11-01';

此外,可以使用DATE()函数代替cast:

SELECT * FROM mytable WHERE DATE(TS) = CURDATE();

问题是哪种方式更正确,更快?因为我不确定所有记录的CAST是一个非常好的主意,也许有更好的方法......

4 个答案:

答案 0 :(得分:4)

好的,我做了一些测试,结果如下。第一个值是TS列上的索引,第二个值是TS列上没有索引。

SELECT * FROM parts WHERE CAST(TS AS DATE) = DATE('2009-10-01');

2.1秒,2.1秒

SELECT * FROM parts WHERE DATE(TS) = DATE('2009-10-01');

2.1秒,2.1秒

SELECT * FROM parts WHERE TS >= DATE('2009-10-01') AND TS < (DATE('2009-10-01') + INTERVAL 1 DAY);

0.1秒,2.15秒

SELECT * FROM parts WHERE TS >= '2009-10-01' AND TS < '2009-10-01 23:59:59';

0.1秒,2.15秒


因此,正如您所看到的,如果我们在TS列上没有索引,则没有区别。但是当我们有索引时,存在很大的差异。当我们在索引列上使用CAST()或DATE()时,索引不能再使用了,所以我们得到了不好的结果。

至于我,我会选择这个解决方案:

SELECT * FROM parts WHERE TS >= DATE('2009-10-01') AND TS < (DATE('2009-10-01') + INTERVAL 1 DAY);

我认为这是最优雅的。

PS。我仍然在寻找更好的解决方案,所以如果你有一个 - 请分享。

答案 1 :(得分:2)

假设你有ts的索引,这将是最快的方式,因为它可以使用该索引:

SELECT *
  FROM mytable
 WHERE ts >= CURDATE()
   AND ts < (CURDATE() + INTERVAL 1 DAY)

答案 2 :(得分:1)

我认为实际上没有在数据库列上运行函数更快,而是做类似这样的事情

SELECT * FROM mytable WHERE TS >= UNIX_TIMESTAMP('2009-11-01 00:00:00') AND TS <= UNIX_TIMESTAMP('2009-11-01 23:59:59');

这样,DB只需要每次运行两个函数,并且可以使用列TS的索引。

答案 3 :(得分:1)

进行一些测试。

我知道我们的数据仓库使用DATE()方法,他们每天处理数百万个交易,所以它不会太糟糕。