在MySql中“汇总”聚合数据的最佳方法是什么?

时间:2012-11-08 16:22:59

标签: mysql

我有一张大表,其中包含按小时划分的每小时统计数据。它现在足够大,我需要开始聚合数据以更快地进行查询。该表看起来像:

customer INT
campaign INT
start_time TIMESTAMP
end_time TIMESTAMP
time_period ENUM(hour, day, week)
clicks INT

我想我可以,例如,在广告系列为空的表格中插入一行,点击次数值将是该客户和时间段的所有点击次数的总和。同样,我可以将时间段设置为“天”,这将是当天所有小时的总和。

我确信这是一件相当常见的事情,所以我想知道在MySql中实现这一目标的最佳方法是什么?我假设INSERT INTO结合了SELECT语句(就像物化视图一样) - 但是由于新数据不断添加到此表中,如何避免重新计算我之前计算过的聚合数据?

2 个答案:

答案 0 :(得分:1)

我做了类似的事情,这就是我遇到的问题:

您可以在“分组依据”部分中使用round(start_time/86400)*86400来获取当天所有条目的摘要。 (一周几乎相同)

SQL将如下所示:

insert into the_table 
( select 
   customer, 
   NULL, 
   round(start_time/86400)*86400, 
   round(start_time/86400)*86400 + 86400, 
   'day', 
   sum(clicks) 
  from the_table 
  where time_period = 'hour' and start_time between <A> and <B> 
  group by customer, round(start_time/86400)*86400 ) as tbl;

delete from the_table 
where  time_period = 'hour' and start_time between <A> and <B>;
  1. 如果要将同一个表中的摘要插入到自身中 - 您将使用temp(这意味着您从表中复制部分数据,而不是删除 - 用于每个事务)。因此,您必须非常小心内部选择返回的索引和数据大小。
  2. 当您不断插入和删除行时 - 迟早会出现碎片问题。它会大大减慢你的速度。解决方案是使用分区&amp;不时删除旧分区。或者你可以运行“优化表”声明,但它会阻止你工作相对较长的时间(可能是几分钟)。
  3. 为避免混淆重复数据 - 您可能希望为每个聚合时段(hour_table,day_table,...)克隆表格。

答案 1 :(得分:0)

如果你试图让表格更小,那么你在制作摘要行后会删除详细的行,对吗?交易是你的朋友。启动一个,计算汇总,插入汇总,删除详细行,结束事务。

如果您碰巧在较旧的时间段内添加了更多行(谁会这样做?),您可以再次运行汇总 - 它会将您之前的汇总条目与您的额外数据合并为一个新的,功能更强大的汇总条目

相关问题