[英]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.