【问题标题】:mySQL - Large metrics table and heavy query performance - Caching?mySQL - 大型指标表和繁重的查询性能 - 缓存?
【发布时间】:2011-03-22 16:05:36
【问题描述】:

我有一个大型数据库,扩展速度非常快,我有许多繁忙的表,记录用户行为的各个方面。

目前,我有一个工作室,用户可以在其中看到明显显示在图表等中的这种用法和行为。问题是,现在加载这些东西非常密集。有一个使用 80,000 人的项目,加载统计数据需要一段时间。

现在,表格的结构非常好,并在连接上建立了索引等。我得到了建议,并在此过程中寻求学习最佳实践,以尝试帮助为这种数据大小做好最好的准备。但是,如果没有更多的查询/表优化范围我还能如何加快这个密集的过程?

我注意到大多数分析等默认情况下允许您查看直到昨天。这有帮助吗?

  1. 这是否意味着统计信息可以被mysql上的query_cache缓存?如果查询在明天不断结束(从而计算今天的统计信息),它不会缓存吗?
  2. 每小时编译可引用的静态 XML 等是否比每次都进行查询更明智?
  3. 还有什么办法?

非常欢迎任何想法。

【问题讨论】:

    标签: php mysql performance metrics


    【解决方案1】:

    您希望将数据拆分为两个数据库。一种针对插入进行了优化以捕获数据。第二个针对数据检索进行了优化。你不能用一个数据库来处理这两项任务。针对大量数据插入进行优化意味着将完成的索引数量减少到绝对最低限度(基本上只是主键),并且在进行数据挖掘时删除键会降低性能。

    所以...两个数据库。将所有数据捕获到插入优化的数据中。然后有一个计划的工作将当天的数据捕获到另一个数据库中,并在那里运行您的分析。

    作为副作用,这是“直到昨天”限制的来源。今天的数据将不可用,因为它位于单独的数据库中。

    【讨论】:

    • 似乎有道理。我会开始朝着这个方向努力。感谢您的想法。
    【解决方案2】:

    如果您不需要显示实时结果;您可以在一天后将结果缓存到 Memcache、APC、Redis 或具有过期缓存的等价物。

    Mysql 会将结果缓存到query_cache。但是你不记得mysql在表/行更改时清除了query_cache。而且它的尺寸有限。

    【讨论】:

      【解决方案3】:

      额外的硬件是不可能的吗?在这种情况下,将数据复制到几个从站可能会加快速度。您还可以使用 Mark B 的版本建议通过仅在非高峰时间(例如通宵)更新从属服务器来拆分数据库。

      【讨论】:

        【解决方案4】:

        Marc B 是对的 - 您希望将数据采集与分析/报告系统分开。

        它的常规名称是“数据仓库”或类似名称。这些往往与您的生产数据库有非常不同的模式 - 高度非规范化或多维“星形”模式很常见。

        如果您看到自己的产品不断增长,您可能希望立即实现飞跃 - 但这是一种全新的技能和技术组合,因此您可能希望采取初步措施。

        在任何一种情况下,都应在物理上独立的硬件上运行您的数据收集和报告数据库。如果您确实采用数据仓库路线,请预算大量磁盘空间。

        【讨论】:

          【解决方案5】:

          您没有确切说明这些表有多大、它们是什么类型的表、它们是如何填充的以及它们是如何使用的。所以,我只是想给出一些随机的想法:)

          当您报告大量数据时,您基本上受限于磁盘系统的速度,即磁盘将数据传输到 MySQL 的速度。此速率通常以兆字节/秒为单位。因此,如果您可以获得 100mb/s,那么如果您想要亚秒级响应时间(暂时完全忽略 DB 缓存),则无法在大于 100mb 的表上执行 select sum() 或 count(*)。请注意,100mb 相当于 2000 万条记录,行大小为 50 字节。
          这在一定程度上起作用,然后一切都消失了。通常当数据库的大小变得大于可用内存并且并发用户数增加时。

          您将需要研究创建聚合表的可能性,以便减少需要扫描的兆字节数。最好用一个例子来解释。假设您当前的度量表如下所示:

          measures(
             user_id 
            ,timestamp
            ,action
          )
          

          对于执行的每一个操作(登录、注销、点击这个、放屁、点击那个),您都会存储用户的 ID 和它发生时的时间戳。

          如果您想绘制从年初开始的每日登录次数,您必须对所有 100,000,000 百万行执行计数 (*) 并按 day(timestamp) 分组。

          相反,您可以提供一个预先计算好的表格,例如:

          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 和特定的 action 来选择最低的详细表是很有可能的。

          【讨论】:

            猜你喜欢
            • 2012-02-07
            • 1970-01-01
            • 1970-01-01
            • 2018-03-06
            • 2016-03-09
            • 2011-03-05
            • 1970-01-01
            • 2014-06-25
            相关资源
            最近更新 更多