大家好,我有非常糟糕的查询,需要优化。
我需要选择创建日期与现在匹配的所有记录 - 35天,但分钟和秒可以是任何记录。
所以我在这里有这个问题,它的丑陋,但有效:
欢迎任何优化提示!
SELECT * FROM outbound_email
oe
INNER JOIN (SELECT `issue_id` FROM `issues` WHERE 1 ORDER BY year DESC, NUM DESC LIMIT 0,5) as issues
ON oe.issue_id = issues.issue_id
WHERE
year(created) = year( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
month(created) = month( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
day(created) = day( DATE_SUB(NOW(), INTERVAL 35 DAY) ) AND
hour(created) = hour( DATE_SUB(NOW(), INTERVAL 35 DAY) )
AND campaign_id IN (SELECT id FROM campaigns WHERE initial = 1)
答案 0 :(得分:0)
我假设该字段"已创建"是一个日期时间字段,来自问题表?由于您在问题和广告系列表格中不需要任何其他内容,因此您可以执行以下操作:
SELECT e.* FROM outbound_email e
JOIN issues i ON e.issue_id = i.issue_id
JOIN campaigns c ON c.id = i.campaign_id
WHERE i.created < DATE_SUB(NOW(), INTERVAL 35 DAY)
AND c.initial = 1
没有必要将日期时间字段分成几年,几个月......等等。
答案 1 :(得分:0)
您似乎在说要从表中选择所有行,其中创建时间与当前时间相同,35天前
SELECT * FROM table WHERE created BETWEEN
DATE_ADD(CURDATE(), INTERVAL (HOUR(now()) - 840) HOUR) AND
DATE_ADD(CURDATE(), INTERVAL (HOUR(now()) - 839) HOUR)
为什么会这样? Curdate今天午夜就给了我们。我们在当前时间加上这个时间(例如假设它现在是下午5点我们将添加'HOUR(NOW()),这将给我们17,现在是下午5点)但我们也减去840因为那是35天*每天24小时= 840小时。因此,添加日期将在当前日期增加-823小时,即35天前的5小时
我们使搜索范围从一小时获得所有记录,一小时后指定的最简单方法是减去839小时而不是840小时
从技术上讲,这个查询也将返回35天之前下午6点(但不是一秒钟之后)的记录,因为介于两者之间(1到10之间也会返回10
如果这是一个问题,请更改created >= blah AND created < blahblah
为了清楚起见,我没有将您的其余查询放入
作为旁注,你做到这一点的方式并不差 - 你可以通过没有年/月/日部分来简化事情,只需将时间部分与date(created) = date_sub(curdate(), interval 35 day)
一起删除,这是将月份和日期组合为日期,没有时间元素。但通常总是最好只保留表格数据而不是格式化或转换它只是为了匹配查询。如果转换表数据,则无法再使用索引。如果您加倍努力将查询参数转换为列的格式,并且不转换表数据,则可以使用列上的索引