2016-11-11 46 views
1

我试图得到一个优化的查询,该查询在任何前一天或某个天数范围内的同一时间给出结果。我能够通过PHP上的一个循环来解决这个问题,重复查询,该查询给出了特定日期的结果,但这需要很长时间。优化MYSQL,PHP在几天前的确切时间搜索记录

我的PHP代码和MySQL查询:

$json_data = array(); 
$i=$range; 
while ($i>0){ 
    $result=mysql_query("SELECT numpeople, numviews, date FROM table_stats ORDER BY ABS(date - DATE_SUB(NOW(), INTERVAL '$i' DAY)) LIMIT 1", $conn); 
    while($r = mysql_fetch_assoc($result)){ 
    $json_data[]= $r; 
    } 
    $i--; 
} 
print json_encode($json_data); 
return; 
+0

您不应该继续使用'mysql_'-函数。请参阅此答案:http://stackoverflow.com/a/13944958/1024057了解更多详情。 –

回答

1

在每一天的时间间隔我会计算你的表达的最低值,并使用加入它背在外部查询到您的统计信息表中的子查询最小值。唯一的问题是,如果你有多个记录的最小差异,那么所有的记录都会被返回。

select numpeople, numviews, date 
FROM table_stats 
inner join 
    (select date(date) dd, min(ABS(date - DATE_SUB(NOW(), INTERVAL (datediff(curdate(), date)) DAY))) as mindiff 
    from table_stats 
    where date(date)<=curdate() - 1 and date(date)>=curdate() - interval $range day 
    group by date(date)) t 
     on t.dd=date(table_stats.date) 
      and t.mindiff=ABS(table_stats.date - DATE_SUB(NOW(), INTERVAL (datediff(curdate(), table_stats.date)) DAY)) 

abs()表达式可以使用concat(date(date), ' ', time(now())),而不是减法日期以获得相同的时间上的前一天。

+0

这实际上效果很好,但如果我将范围设置为高于11,并且有12个或更多的范围返回所有结果,则会中断。我的猜测是因为它改变了几个月......我不知道足够的SQL来计算这个数据,但速度更快 – Marco

+0

嗯,用curdate()替换'curdate() - $ range' - interval $ range day' – Shadow

+0

是的,那是完美的。非常感谢你......我一直在努力解决这个问题。 – Marco

0

作为替代版本:

SELECT numpeople, numviews, `date` FROM table_stats 
WHERE `date` < NOW() - INTERVAL $n DAY -- where $n is the max range 
AND TIME(`date`) BETWEEN TIME(NOW()) - INTERVAL 5 MINUTE AND TIME(NOW()) + INTERVAL 5 MINUTE 
ORDER BY date DESC 
LIMIT 1 

查找所有记录与+/- 5分钟的当前时间的条目,最多$n天前。

+0

这将是丑陋的,但你可能会发现最快的方法是预先计算确切的时间范围在PHP和查询这些间隔。 –

+0

你是对的,这个查询(在开始时没有“ - INTERVAL $ n DAY”)工作得更快,几乎给了我答案,但不幸的是它在同一天返回多行。如果没有,我可以将结果限制在范围内,因为所有结果都从现在开始()到过去。谢谢 – Marco