我有一个庞大的数据库,非常迅速地扩展,我有很多忙碌的表,记录了用户行为的各个方面。
目前,我有一个工作室,用户可以看到这种用法和行为明显显示在图表等等。事情是,现在加载这些东西严重密集。有一个项目使用了80,000人,并且需要一个年龄来加载统计数据。
现在,表结构非常合理,并且在连接上编制索引等。我已经有了建议,并寻求学习最佳实践,以尝试帮助最好地准备这些数据。但是,在查询/表格优化中没有更多的范围如何才能加快这一密集型流程?。
我注意到大多数分析都允许您默认查看到昨天。这有帮助吗?
非常欢迎任何想法。
答案 0 :(得分:7)
您希望将内容拆分为两个数据库。一个针对插入进行了优化以捕获数据。第二个针对数据检索进行了优化。使用单个数据库处理这两个任务时,您无法执行此操作。优化大量数据插入意味着减少绝对最小化索引的数量(基本上只是主键),并且在进行数据挖掘时删除键会导致性能下降。
所以...两个数据库。将所有数据捕获到插入优化的数据中。然后将当天的数据捕获计划到另一个数据库中,并在那里运行您的分析。
作为副作用,这是“直到昨天”限制的来源。今天的数据将无法在单独的数据库中使用。
答案 1 :(得分:1)
如果您不需要显示实时结果;您可以在一天后将结果缓存到Memcache,APC,Redis或equilevent以及expire缓存。
Mysql将缓存结果发送到query_cache。但你不记得mysql在更改表/行时清除query_cache。它的尺寸有限。
答案 2 :(得分:1)
额外的硬件是不可能的吗?在这种情况下,将数据复制到少数从站可能会加快速度。您也可以使用版本Mark B的建议来拆分数据库,只需在非高峰时间更新奴隶,例如,隔夜。
答案 3 :(得分:1)
Marc B是对的 - 您希望将数据捕获与分析/报告系统分开。
传统的名称是“数据仓库”或类似名称。这些模式往往与生产数据库有非常不同的模式 - 高度非规范化或多维“星形”模式很常见。
如果你看到你的产品不断增长,你可能想要立即跳转 - 但这是一项全新的技能和技术设置,所以你可能想要采取一些步骤。
在任何一种情况下,都要在物理上独立的硬件上运行数据收集和报告数据库。如果你确实去了数据仓库路线,那就预算了大量的磁盘空间。
答案 4 :(得分:1)
你没有确切地说这些表有多大,它们是什么类型的表,如何填充表以及如何使用它们。所以,我只想提出一些随意的想法:)
当您报告大量数据时,基本上只限于磁盘系统的速度,即磁盘将数据传递给MySQL的速度。此速率通常以兆字节/秒为单位。因此,如果您可以获得100mb / s,那么如果您想要亚秒响应时间(稍微完全忽略数据库缓存),则不能对大于100mb的表执行select sum()或count(*)。请注意,100mb将是2000万条记录,行数为50字节 这可以达到一定程度,然后一切都会消失。通常当数据库的大小变得大于可用内存并且并发用户数增加时。
您需要调查创建聚合表的可能性,以便您可以减少需要扫描的nr兆字节。最好用一个例子来解释。假设您当前的度量表看起来像这样:
measures(
user_id
,timestamp
,action
)
对于执行的每个操作(登录,注销,单击此项,放屁,单击该操作),您可以存储用户的ID以及发生时间的时间戳。
如果要绘制年初的每日登录次数,则必须按day(timestamp)
对所有100,000,000,000行和分组执行计数(*)。
相反,您可以提供一个预先计算的表格,例如:
daily_actions(
day
,action
,occured
,primary key(day, action)
)
该表通常会加载如下内容:
select day(timestamp)
,action
,count(*)
from measures
group
by day(timestamp)
,action
如果您有100个可能的操作,则只需要36,500行来存储整年的活动。运行统计信息,图表,报告以及不包含该数据的用户不会比典型的OLTP事务更重。当然,您也可以每小时(或相反)存储它,并在一年内达到876,000行。您还可以使用上表报告每周,每月,每三年或每年的数字。 如果您可以将用户操作分组为操作类别,请说“有趣”,“不那么有趣”,可能有害“和”错误“您可以将存储从100个可能的操作进一步减少到4个。
显然,您的数据比这更复杂,但您几乎总能找到合适的nr聚合表,几乎可以回答高聚合级别的任何问题。通过聚合表“深入”后,您可以使用所有这些过滤器,然后您可能会发现使用特定的date
和特定的{{1}可以选择最低详细的表格。 }。