如何以最有效的方式跟踪观看次数?

时间:2009-09-18 16:05:34

标签: mysql performance insert

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

请注意,我无法使用任何分析工具,因为我需要使用这些数字(最受欢迎等)。

3 个答案:

答案 0 :(得分:2)

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

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

  • 每次查看文章时都执行原始插入,并且不进行更新
  • 或更新每个文章的计数器,在该临时表中
  • (如果您使用的InnoDB引擎支持行锁,并且不使用表锁)每篇文章使用100行,并且每次都会随机更新其中一行文章被查看
    • 通过这种方式,您可以减少锁定的并发性(如果您有5个用户在同一时间阅读同一篇文章,那么他们将尝试在100个中更新同一行的风险不大! )
    • 请记住,您需要对每篇文章的100行进行求和,以便在计算文章被查看次数时获得“总计”。

在并发方面,最后一个解决方案可能是最好的解决方案 - 再次,如果您使用的是支持行锁(即非MyISAM)的引擎

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

答案 1 :(得分:2)

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

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

我建议:

  1. 使您的读取无锁定(NOLOCK),并且仅使用锁定进行写入。因此,您只是阻止同时更新视图计数,而不是读取文章数据。
  2. 如果这还不够好,并且您可以忍受一些边缘情况丢失视图计数,请以异步方式进行视图计数更新,并且不要等待它返回以显示页面。
  3. (通过边缘情况丢失视图计数,我的意思是在您发送页面后异步写入失败的情况,因为您的数据库在读取文章数据之后但在查看计数更新之前就已关闭)

答案 2 :(得分:1)

“最有效的方式”是非常主观的;你必须启发我们你的具体表现问题。

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

摘要生成器会计算一段时间内日志文件中每篇文章的浏览次数(比如每分钟或每两分钟运行一次),然后在单个事务中执行,但需要进行多次更新,每篇文章一次。这些可能不会引起太多问题,因为您每个网络服务器只需要一个进程每分钟执行一个事务(或者2个,或5个或多个),而不是每个Web请求一个。数据库上的负载会少很多。