【问题标题】:How to track number of views in the most efficient way?如何以最有效的方式跟踪视图数量?
【发布时间】:2009-09-18 16:05:34
【问题描述】:

我有这个类似博客的系统 (LAMP),我想跟踪每篇文章的浏览量。现在,每次查看文章时更新文章的 views 列更好还是使用一些临时表,我只存储文章 ID,然后(假设每小时)运行查询将从临时表中获取数据并更新 articles 表中的行?我对完全不同的解决方案持开放态度。

请注意,我不能使用任何分析工具,因为我需要处理这些数字(最流行等)。

【问题讨论】:

  • 你没有说明你有多少个网络服务器,以及它们是否都与数据库位于同一位置,但我下面的回答可能会相当有效,即使它们相当多并且其中一些不是。

标签: mysql performance insert


【解决方案1】:

每次阅读文章时更新文章表将意味着更多锁定此表(或行,取决于您使用的引擎)

在我看来,使用临时表可能是一个更好的解决方案:

  • 每次查看文章时都执行原始插入,并且不更新
  • 或在该临时表中为每篇文章更新一个计数器
  • (如果您使用的引擎如 InnoDB 支持行锁,但不使用表锁)每篇文章使用 100 行,并在每次文章被查看
    • 这样,锁的并发性就会降低(如果您有 5 个用户在同一时间阅读同一篇文章,那么他们尝试更新 100 行中的同一行的风险并不大! )
    • 请记住,当您想计算一篇文章的浏览次数时,您必须将每篇文章 100 行的值相加,才能得到“总和”。

就并发性而言,最后一种解决方案可能是最好的解决方案——再一次,如果您使用的引擎支持行锁(即不是 MyISAM)

并且,偶尔运行一个将从该临时表计数的 cron 作业,并更新文章表。

【讨论】:

    【解决方案2】:

    这可能是过早优化的情况吗? 在极端地使用单独的表和运行 cron 作业之前,我会确保正确调整简单的方法是一个问题。

    此外,您的问题是写锁争用,通过写入另一个表,您只是将该争用移至该表,并且将具有相同的阻塞。

    我建议:

    1. 使您的读取不带锁 (NOLOCK),而只有带锁的写入。因此,您只会阻止查看次数的同时更新,而不是文章数据的读取。
    2. 如果这还不够好,并且您可以忍受某些极端情况下的视图计数丢失,请异步更新视图计数,不要等待它返回显示页面。

    (通过视图计数的边缘情况丢失,我的意思是在您交付页面后异步写入失败的实例,因为您的数据库在读取文章数据之后但在更新视图计数之前发生了故障)

    【讨论】:

      【解决方案3】:

      “最有效的方式”是相当主观的;您必须让我们了解您的具体性能问题。

      我可能会将页面视图(在场中的每个 Web 服务器中)附加到本地日志文件(当然是原子的),然后有一个进程定期轮换并将其汇总到数据库中(当然句柄正确的并发访问;留给读者练习)。

      摘要器会计算日志文件中每篇文章在一段时间内的查看次数(比如每分钟或每两分钟运行一次),然后在单个事务中执行,无论需要多少更新,每篇文章一个。这些可能不会造成太大的问题,因为您只会查看每台 Web 服务器的一个进程每分钟执行一项事务(或 2 个、5 个或许多),而不是每个 Web 请求一个。数据库的负载会少很多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 2019-09-03
        相关资源
        最近更新 更多