【问题标题】:Fastest way to increment a field in the database在数据库中增加字段的最快方法
【发布时间】:2011-12-08 21:20:03
【问题描述】:

假设我有一个保存页面访问计数的 MySQL 表,并且我想跟踪每个用户的页面访问总数。下面是增加字段的 SQL:

UPDATE visits  
  SET visits = visits + 1  
  WHERE user_id = 12

这很简单,但我想知道是否有更快的方法来实现这一点。我的意思是,如果我有很多访问者(理想情况下每天有数百万用户),这种方法是否足够,或者我应该使用另一种方法。谢谢。

【问题讨论】:

  • 最快的方法是通过 mySQL 本身,这通常是您当前通过查询进行的。我能想到的任何其他选择都需要将数据拉出,用 php 对其进行更改,然后将数据放回原处。如果您需要做的只是在可以通过查询来增加一列时,这是多余的。
  • 坚持下去。如果您的 user_id 是主键(理想情况下是 auto_increment),那么您就在正确的轨道上。在考虑 1 mio 时,您需要担心的语句会变慢。用户(更不用说浏览量和查询)。

标签: php mysql database


【解决方案1】:

使用user_id 上的索引,这将非常快。我怀疑您是否能够使用任何其他方式获得(明显)更快的结果。除了这个查询之外,您可能会遇到数百万用户的其他性能/服务器问题(有人称之为“微优化”)

【讨论】:

  • 这些类型的查询在高读取站点上实际上可能是相当具有破坏性的,尤其是在 MyISAM 上...折腾到辅助存储区域并批量更新确实有很大帮助。
  • @AdrianSchneider - 什么数据让你得出这个(主观)结论?
  • 处理高流量网站的个人经验。使用表级锁定,每次更新都会在瞬间锁定表。如果这种情况总是不停地发生,则表每秒都在不断地锁定。显然,行级锁定要好得多,但我仍然想避免这种情况。对于低流量网站来说不是问题。
  • 所以表锁定是一个障碍,并且通过 InnoDB 得到缓解?
  • Facebook 是一个特例,因为他们使用 HipHop for PHP 和 memcached 来提高其应用程序的可扩展性。
【解决方案2】:

我认为这不会明显更快,但您可以做的一件事是堆叠他们的访问并通过 cron 作业每分钟更新一次点击次数。只需确保 user_id 已编入索引

【讨论】:

  • 唯一的问题是缓存是不稳定的,所以如果键/值对丢失,他将失去他的访问次数。
  • @Col.Shrapnel:这只是一个例子
  • +1 您还可以让应用程序每增加 1000 次 memcached 键就更新一次数据库。如果 memcached 崩溃,通过 RAND()*1000 更新数据库中的访问。
  • 哈哈很好的解决方案!只需在一天结束前通过 RAND()*1000 更新它,根本不用缓存 :)
  • @BillKarwin:嗯,我认为这不是一个好的解决方案。我已经删除了 memcached 作为解决方案,因为它往往会崩溃
【解决方案3】:

使用visits 上的索引可能会很慢。
尽管我建议您保持原样,直到您获得至少 10 000 个用户为止。
因为在那之前你将不得不多次重写你的代码。

【讨论】:

  • 假设您有 10 000 个用户。那么你会建议什么作为解决方案呢?
  • 这取决于使用了这么一个相当没用的数字。首先,我根本不会为这样一个愚蠢的计数器而烦恼,而是使用谷歌计数器或实现一些日志分析器。但是正如您所期望的数据库解决方案一样,我会将此字段设为非索引并实施一些离线统计信息聚合器来获取数字。虽然每天有 10K 访问者,但仍然完全没有必要。
  • 谢谢。好吧,首先,我用这个“愚蠢”的代码简化了我的需求。在实践中,我没有使用此代码,只是这些类型问题的示例。第二,你能解释一下关于谷歌计数器的更多信息吗?我想了解更多。再次感谢。
  • @AlirezaNoori 我的意思是谷歌分析。一个强大的访问次数统计工具。
猜你喜欢
  • 2018-02-09
  • 2016-04-05
  • 2015-05-07
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 2012-07-24
  • 2011-04-02
  • 2011-04-28
相关资源
最近更新 更多