2013-01-20 113 views
0

我想按照时间戳的小时数从MYSQL数据库中获取结果。时间戳以2012-12-14 03:19:09的格式存储在表中。我用的是查询按日期分组MYSQL结果行

SELECT 
    HOUR(`timestamp`) AS `hour`, 
    AVG(`somevalue`) AS `average` 
FROM ... 
GROUP BY 
    HOUR(`timestamp`), 
    DAY(`timestamp`), 
    MONTH(`timestamp`), 
    WEEK(`timestamp`), 
    YEAR(`timestamp`) 
ORDER BY ... 
LIMIT 0, 24; 

这工作,并返回正确的行数和值...

+------+-------+ 
| hour | value | 
+------+-------+ 
| 13 | 21.16 | 
| 12 | 21.11 | 
| 11 | 20.88 | 
| 10 | 20.93 | 
| 9 | 20.87 | 
| 8 | 20.89 | 
| ... | ... | 
+------+-------+ 

...但极其缓慢(表包含〜90K行)。我是given the advice不是按每个日期实体分组,而是按UNIX_TIMESTAMP(`timestamp`)/3600分组。这不幸的是不会导致预期的结果,结果看起来像这样

+------+-------+ 
| hour | value | 
+------+-------+ 
| 13 | 21.20 | 
| 13 | 21.20 | 
| 13 | 21.20 | 
| 13 | 21.20 | 
| 13 | 21.20 | 
| ... | ... | 
+------+-------+ 

有什么办法给他们组只有一个group子句(这将使其更快),但返回正确的结果?

+0

使用多个反引号没有在这里工作,我(见上文)使用组。如果有人发现错误,我很感谢您的纠正。 –

+0

没有试图用当前模式解决这个问题*将避免全表扫描和文件,所以对于大型表格将变得非常昂贵。您需要更改模式,以便可以将索引分组,例如,通过在另一个(索引)列中存储'DATE_FORMAT(时间戳,'%Y-%m-%d%H:00:00')' 。 – eggyal

回答

1

而不是做它的日期和时间

SELECT 
    HOUR(`timestamp`) AS `hour`, 
    AVG(`somevalue`) AS `average` 
FROM ... 
GROUP BY 
    DATE(`timestamp`), 
    HOUR(`timestamp`), 
ORDER BY ... 
LIMIT 0, 24; 
+0

看起来很有希望:是1.4012秒,现在是0.9345。快三分之一! –

+0

欢迎感谢! –

0
  1. 索引时间戳列。
  2. 尝试GROUP BY DATE_FORMAT(timestamp,'%Y%m%d%H')

请注意,我自己并没有真的试过这个。

+0

时间戳列已编入索引。 –

+0

没有性能改进:1.5021而不是1.4012秒(约增加7%)在我的机器上。 –