1

我有一个大表,其中包含按多个维度细分的每小时统计数据。它现在足够大,我需要开始聚合数据以加快查询速度。该表看起来像:

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

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

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

4

2 回答 2

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. 当您不断插入和删除行时 - 您迟早会遇到碎片问题。它会大大减慢你的速度。解决方案是使用分区 & 不时删除旧分区。或者您可以运行“优化表”语句,但它会阻止您工作相对较长的时间(可能是几分钟)。
  3. 为避免重复数据混乱 - 您可能希望为每个时间聚合周期(hour_table、day_table、...)克隆表
于 2013-04-21T12:15:06.353 回答
0

如果您试图使表格更小,您将在创建摘要行后删除详细行,对吗?交易是你的朋友。开始一个,计算汇总,插入汇总,删除详细行,结束事务。

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

于 2012-11-09T17:49:31.770 回答