Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在24小时时间窗口中检索数据的日期条件_Mysql_Sql_Perl_Cron - Fatal编程技术网

Mysql 在24小时时间窗口中检索数据的日期条件

Mysql 在24小时时间窗口中检索数据的日期条件,mysql,sql,perl,cron,Mysql,Sql,Perl,Cron,我正在使用perl和DBI查询mysql表。我需要在过去24小时内检索所有行(从3个单独的数据库中检索大约75000行),最好是在上午12:00到晚上11:59或00:00到23:59之间 我使用了一个,其中日期条件如下: SELECT * FROM table_name WHERE insert_date >= DATE_SUB(NOW(), INTERVAL 1 DAY); SELECT * FROM table_name WHERE insert_date BETWEEN D

我正在使用perl和DBI查询mysql表。我需要在过去24小时内检索所有行(从3个单独的数据库中检索大约75000行),最好是在上午12:00到晚上11:59或00:00到23:59之间

我使用了一个
,其中
日期条件如下:

SELECT * 
FROM table_name
WHERE insert_date >= DATE_SUB(NOW(), INTERVAL 1 DAY);
SELECT * 
FROM table_name
WHERE insert_date 
BETWEEN DATE_SUB(DATE_SUB(NOW(), INTERVAL 3 HOUR), INTERVAL 1 DAY) 
AND DATE_SUB(NOW(), INTERVAL 3 HOUR);
然后我会在午夜使用cron运行我的脚本。这已经足够好了,但是由于午夜经常有大量的流量和查询的大小,cron计划的执行时间现在是凌晨3:00。我更改了sql以尝试从如下偏移量获取相同的24小时周期:

SELECT * 
FROM table_name
WHERE insert_date >= DATE_SUB(NOW(), INTERVAL 1 DAY);
SELECT * 
FROM table_name
WHERE insert_date 
BETWEEN DATE_SUB(DATE_SUB(NOW(), INTERVAL 3 HOUR), INTERVAL 1 DAY) 
AND DATE_SUB(NOW(), INTERVAL 3 HOUR);
对于我来说,这似乎很好,但我想问,是否有一种更可读、更准确的方法,使用mysql,在从偏移时间运行查询时,每天获取一次过去24小时(在00:00:00和23:59:59时间窗口之间)中的所有行?我对所有这些都是新手,所以对我的总体方法的任何批评都是非常受欢迎的

BETWEEN DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY), "%Y-%M-%d 00:00:00")
    AND DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY), "%Y-%M-%d 23:59:59")

您还可以使用Perl日期格式化函数生成相同的日期时间字符串,并将它们插入查询。

我认为
insert\u date
DATETIME

建立两个限制并在
之间使用
,这似乎毫无意义。我只需检查
日期(插入日期)
是否是昨天的日期。所以

WHERE DATE(insert_date) = CURDATE() - INTERVAL 1 DAY

考虑到
DATE(NOW())
暗指今天早上的午夜,显而易见的解决方案是取该值并减去一天作为开始。。。最后减去一秒

BETWEEN DATE_SUB(DATE(NOW()), INTERVAL 1 DAY)
    AND DATE_SUB(DATE(NOW()), INTERVAL 1 SECOND)

下限将被强制为昨天的YYYY-MM-DD 00:00:00,其中谓词将能够使用
insert\u date

上的索引。这非常有效,我只需在格式字符串中添加
%
百分号,并使用小写的m,如:%Y-%m-%d@这是一种获取一天中特定时间的简单方法。我认为这不会对性能造成显著影响,因为整个查询只需对字符串进行一次分析,然后它就会进行日期比较(如果他的
insert\u date
列被索引,这将只是索引扫描)。是的,对不起,我太仓促了。我没有注意到您对日期应用了特定的时间。
date(NOW())
的传统拼写是
CURDATE()
。此外,我怀疑是否有特殊要求排除在午夜前最后一秒创建的记录。这就是不知名的bug是如何产生的。这绝对没有什么不知名的。BETWEEN是包含的,因此不排除在最后一秒创建的内容。另外,使用DATE(NOW())可以用任何时间戳来代替NOW()。这是一个很好的主意。如果每天都运行查询,您就不希望精确在午夜出现的记录被处理两次。
DATE(NOW())
今天是
00:00:00
,所以
DATE(DATE(NOW()),INTERVAL 1秒)
(或者更清楚地说,
CURDATE()-INTERVAL 1秒
)是
23:59:59
。介于
之间的
不会神奇地包含从那到午夜之间的时间,也不应该包含。如果是这样的话,你认为减去一秒钟有什么区别?您是否认为,如果没有它,它将包括直到
00:00:01
的记录@巴尔马:是的,我同意。正如我在对这个问题的评论中所说的那样,你不能在
之间做这件事,因为它总是包括范围的开始和结束限制。相反,您必须使用
time>=开始和时间
。您确实不想要
00:00:00
23:59:59
的范围。这样,您将排除在一天的最后一秒创建的任何记录。你可能不期望有,但这不是重点。您需要从
00:00:00
到第二天的
00:00:00
之间的所有内容。不,您不能使用介于
之间的
执行此操作,但您可以使用
插入日期>=开始时间和插入日期<结束时间
。或者,在这种情况下,只检查日期而忽略时间要简单得多。请看下面我的答案。@Barmar:我相信MySQL比这更智能,因为将
DATETIME
转换为
DATE
非常常见,它会缓存转换。但是你的评论和这个都是推测性的,除非你有任何证据,否则这不是建设性的。嗯,有人删除了我的评论,这表明这种形式的查询无法优化。看起来它取决于版本。我在自己的5.1系统上尝试了它,但它没有索引,但是运行5.5的sqlfiddle使用了索引。