MySQL SELECT WHERE日期时间匹配日期(不一定是时间)


127

我有一个包含datetime列的表。我希望无论何时都返回给定日期的所有记录。换句话说,如果我的表仅包含以下4条记录,那么如果我限制为2012-12-25,则仅返回第二和第三条记录。

2012-12-24 00:00:00
2012-12-25 00:00:00
2012-12-25 06:00:00
2012-12-26 05:00:00

Answers:


326

永远不要使用像这样的选择器DATE(datecolumns) = '2012-12-24'-它是性能杀手:

  • 它将计算DATE()所有不匹配的行,包括那些不匹配的行
  • 它将不可能使用索引进行查询

使用起来更快

SELECT * FROM tablename 
WHERE columname BETWEEN '2012-12-25 00:00:00' AND '2012-12-25 23:59:59'

因为这将允许索引使用而无需计算。

编辑

正如Used_By_Already所指出的那样,自2012年最初答复以来,已经出现了MySQL的一些版本,在这些版本中使用'23:59:59'作为结束日不再安全了。更新后的版本应为

SELECT * FROM tablename 
WHERE columname >='2012-12-25 00:00:00'
AND columname <'2012-12-26 00:00:00'

答案的要旨,即在计算出的表达式上避免选择器,当然仍然有效。


我要评论的是a1ex07的解决方案似乎不如其他解决方案好。阅读您的帖子后,也许我需要扭转思路!
user1032531

2
刚刚在两台服务器上进行了测试,以上内容比date()=''快了至少10倍),特别是对于大型表。谢谢
zzapper 2014年

1
@KonradViltersten我使用了一种非常冗长的方式来表达查询的短语,以使其更具可读性,并阐明我的观点,从而完善了它。a1ex07的答案具有稀疏语法。
尤金·里克

9
@KonradViltersten -更重要的是:WHERE col >= '2012-12-25' AND col < '2012-12-25' + INTERVAL 1 DAY。它避免了0时间和工程DATEDATETIMEDATETIME(6),等。随着闰日等交易
里克·詹姆斯

1
“ 2012-12-25 23:59:59”在一天结束时无效,这始终是个坏主意,并且会导致支持亚秒级时间精度的MySQL版本出现错误。最好使用Rick James(上)或a1ex07(其他答案)的方法
Used_By_Already

34

... WHERE date_column >='2012-12-25' AND date_column <'2012-12-26'(如果您在date_column上有索引)可能比更好地工作DATE


1
我实际上想知道什么是更快的-这或BETWEEN解决方案...有人委托吗?
jave.web 2015年

6
应该没什么区别。BETWEEN只是一种写法field >= value1 and fied<= value2
a1ex07

1
请注意,根据《 MySQL手册》:“为了在将BETWEEN与日期或时间值一起使用时获得最佳结果,请使用CAST()将这些值显式转换为所需的数据类型。示例:如果将DATETIME与两个DATE值进行比较,请转换DATE如果将字符串常量(例如'2001-1-1')与DATE进行比较,则将该字符串转换为DATE。” 因此,除非它们都是相同的类型,否则最好将其显式转换。
techdude

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.