数据库:聚合与存储预先计算的数据,以便在大型数据存储中查找?

时间:2017-11-08 16:52:23

标签: mysql performance database-design database-performance

我们有一张包含200万条记录的表格,每分钟有30条记录新的行插入。

表结构是: |投诉|手机| RequestDateTime | 。我们得到抱怨,移动用户和当前日期,我们将其保存在此表中。在此表中我们可以有多个具有相同移动设备的行。

如果我们在过去30天内收到来自同一“移动”的12个请求,我们只需要保存新记录。我们有三种方法来计算特定移动设备的记录数量:

  1. 每次插入新记录之前,首先在数据库中运行聚合查询,以检查我们是否已有12条带有该数字的记录。如果是,请不要插入新的。这里的问题是查询的性能。
  2. 或者在日期结束后存储此数据,即表格中过去29天内具有相同手机号码的行,并仅在当天运行汇总,并添加两者以检查其是否小于12。
  3. 或者有人可以建议更好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

另一种更好的方法是:

1)在每个EOD,维护一个负面的移动列表(没有投诉> 12)。

2)如果记录是该列表的一部分,您将永远不会处理该记录。即使你可以将这些记录缓存在内存中(取决于你正在使用的技术)并避免DB调用。

3)(可选)您可以安排批处理(比方说每小时),这可以使用其他项目和缓存更新否定列表。

根据评论编辑

4)如果您没有在否定列表中找到记录,请继续使用正常的计数逻辑。

5)您可以扩展LRU(最近使用的最少)缓存策略,以便为频繁记录保留内存计数,以避免进行数据库调用。一旦在主DB中插入12条记录,请务必将记录刷新到否定列表中。

答案 1 :(得分:1)

我会做出即时检查的论据......

这是查询,对吗?

SELECT COUNT(*)
    FROM tbl
    WHERE num = 1234
      AND datetime >= NOW() - INTERVAL 30 DAY; 
  • 每秒不到一INSERT
  • 查询永远不会超过12,是吗?
  • 使用INDEX(num, date)SELECT 非常快。
  • 现在您的查询速度为60次/分钟(1次/秒)。 (一个SELECT +(通常)一个INSERT)在超过100秒/秒之前,事情不会变得冒险。
  • BTree索引非常有效,并且不受表大小的影响。因此,2M行不是一个因素。也不会20亿。
  • 我建议这个解决方案比其他选择简单。 KISS。

(我是摘要表的主要支持者,但我不能在这里证明它。)