繁体   English   中英

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

[英]Which is the best way to check if timestamp/datetime belongs to a specified date

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

我通常这样做:

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

另外,可以使用DATE()函数代替强制转换:

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

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

好的,我做了一些测试,这是结果。 第一个值在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。 我仍在寻找更好的解决方案,因此,如果您有一个-请分享。

假设您在ts上有一个索引,这将是最快的方法,因为它将能够使用该索引:

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

我认为实际上不在数据库列上运行函数而是执行类似的操作更快

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列的索引。

运行一些测试。

我知道我们的数据仓库使用DATE()方法,并且它们每天要处理数百万个事务,因此这不会太糟。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM