Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何以最有效的方式跟踪视图数?_Mysql_Performance_Insert - Fatal编程技术网

Mysql 如何以最有效的方式跟踪视图数?

Mysql 如何以最有效的方式跟踪视图数?,mysql,performance,insert,Mysql,Performance,Insert,我有一个类似博客的系统(LAMP),我想跟踪每篇文章的浏览量。现在,是否最好在每次查看文章时更新文章的views列,或者使用某个临时表(我只存储文章ID),然后(比方说每小时)运行一个查询,从临时表获取数据并更新文章表中的行?我对完全不同的解决方案持开放态度 请注意,我不能使用任何分析工具,因为我需要处理这些数字(最流行的数字等)。每次阅读文章时更新文章表将意味着更多地锁定此表(或行,具体取决于您使用的引擎) 在我看来,使用临时表可能是更好的解决方案: 或者在每次查看文章时进行原始插入,而不进

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


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

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

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

  • 或者在每次查看文章时进行原始插入,而不进行更新
  • 或者在临时表中更新每篇文章的计数器
  • 或者(如果您使用的是像InnoDB这样的引擎,它支持行锁,而不使用表锁),则在每篇文章中使用大约100行,并在每次查看文章时随机更新其中一行
    • 这样,锁上的并发性就会减少(如果有5个用户在同一时间阅读同一篇文章,那么他们尝试更新100个用户中的同一行的风险就不大了!)
    • 请记住,当您想计算一篇文章被浏览的次数时,您必须对每篇文章100行的值求和,才能得到“总计”
就并发性而言,最后一个解决方案可能是最好的解决方案——如果您使用的是支持行锁的引擎(即不是MyISAM)


每隔一段时间,运行一个cron作业,该作业将从临时表中计数,并更新文章表。

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

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

我建议:

  • 使读操作不带锁(NOLOCK),而写操作只带锁。所以,您只阻止同时更新视图计数,而不阻止读取文章数据
  • 如果这还不够好,并且您可以忍受一些边缘情况下的视图计数丢失,请异步更新视图计数,不要等待它返回显示页面
  • (所谓边缘案例丢失视图计数,我指的是在交付页面后异步写入失败的情况,因为您的DB在读取文章数据之后,但在更新视图计数之前就下降了)

    “最有效的方法”是非常主观的;您必须告诉我们您的具体性能问题

    我可能会让页面视图(在服务器场中的每个web服务器中)附加到本地日志文件(当然是原子性的),然后让一个进程定期循环并将其汇总到数据库中(当然,正确处理并发访问;这留给读者作为练习)


    summariser会在一段时间内计算日志文件中每篇文章的视图数(比如说每一两分钟运行一次),然后在单个事务中,不管需要多少次更新,每篇文章都会有一次更新。这些可能不会引起太多的问题,因为您将看到每个web服务器只有一个进程每分钟执行一个事务(或2个、或5个或多个),而不是每个web请求执行一个事务。数据库上的负载会小得多。

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