如果您正在进行min / max / avg查询,是否更喜欢使用聚合表或只是在原始表中的一系列行中进行查询?
这显然是一个非常开放的问题,没有一个正确的答案,所以我只是在寻找人们的一般性建议。假设原始数据表包含时间戳,数字外键(例如用户ID)和小数值(比如购买金额)。此外,假设表中有数百万行。
我做了两件事并且被撕裂了。一方面,聚合表给了我明显更快的查询,但代价是增加了额外的表。显示聚合范围的当前值要么完全退回到原始数据表,要么组合更细粒度的聚合。我发现在应用程序代码中跟踪哪个聚合表来查询何时需要更多工作,并且需要进行模式更改,因为原始聚合范围总是不够(“但我想看到我们在过去3个工资期内的销售额!“)。
另一方面,从原始数据查询可能会非常缓慢,但让我对数据范围非常灵活。当范围边界发生变化时,我只需更改查询而不必重建聚合表。同样,应用程序代码需要更少的更新我怀疑如果我对我的索引更聪明(即总是有良好的覆盖索引),我将能够减少从原始数据中选择的惩罚,但这绝不是灵丹妙药。
无论如何,我可以两全其美吗?
答案 0 :(得分:3)
我们遇到了同样的问题并遇到了您遇到的同样问题。我们最终将报告切换到Analysis Services。 MDX和Analysis服务本身有一个学习曲线,但它很棒。我们发现的一些好处是:
一些缺点:
更新: 由于您使用的是MySql,因此可以查看Pentaho Mondrian,这是一个支持MySql的开源OLAP解决方案。我从来没用过它,所以我不知道它是否适合你。有兴趣知道它是否适合你。
答案 1 :(得分:0)
我总是倾向于原始数据。汇总后,您无法返回 与删除无关 - 除非有最简单的聚合数据集,否则无法准确地将数据还原/转置回原始数据。
理想情况下,我使用物化视图(假设数据可以在约束内),因为它实际上是一个表。但是MySQL不支持它们,因此下一个考虑因素是使用计算列的视图,或者更新实际表的触发器。
答案 2 :(得分:0)
选择一个好的主键(即[user_id,used_date,used_time])会有所帮助。对于常量user_id,在used_date上执行范围条件非常快。
但随着表的增长,您可以通过聚合到[user_id,used_date]这样的表来减少表大小。对于时间无关紧要的每个范围,您都可以使用该表。减少表大小的另一种方法是归档您不再(允许)查询的旧数据。