每次维护单独的计数表与运行计数查询是否更好?

时间:2011-08-23 11:37:20

标签: sql database performance

我正在构建一个社交应用程序,它具有类似于twitter的跟随/跟随概念。

从性能的角度来看,找不到关注者和关注用户,是否最好为计数维护一个单独的表?或者每次只进行一次计数查询?

更新

同样地,我有一种调查功能,人们可以投票,人们只能投票是或否。现在我将投票存储在一个单独的表中。我需要在没有参与者的情况下显示调查列表,在我的主页上显示是和否的调查。

类似于stackoverflow主页(其中显示了投票,答案和视图的数量)。

3 个答案:

答案 0 :(得分:7)

这与大多数情况一样,取决于访问模式,即系统的使用方式。如果更新将是您的主要瓶颈,那么您不应该通过维护计数器来增加额外的开销。另一方面,如果访问具有计数准备的数据将为您节省大量时间,或者每次计数都是不可行的,那么您应该预先计算它。

作为一般准则,不要在实际测量性能成为问题之前添加表,例如您建议的单独计数表,这些表纯粹用于性能优化。有一个单独的计数表会打破规范化(因为任何类型的缓存都会这样,因为数据现在在两个地方被复制)并且会使代码更复杂,因此不应该只是因为可能需要计数。

(总而言之,一些数据库支持materialized views / materialized queries,允许您在后台透明地轻松进行这种缓存。这些物化表由数据库更新,因此程序代码不必担心它还取决于查询优化器的复杂程度,可用于透明地优化查询。)

<强>更新 No / Yes投票问题有点不同,主要目的是跟踪计数,不一定是整个信息(即投票赞成的人)。因此,有效的实施可能只是跟踪是和否投票的累计数量。但是,你存储的信息越多(即谁投票赞成,而不仅仅是很多),如果你选择这样做,你可以用它做的越多(例如,在Stackoverflow中我总是可以删除我的upvote - 如果你不能做你没跟踪谁投票)。在这种情况下,我会建议反对早期汇总,因为你会丢失某些信息。

答案 1 :(得分:2)

取决于。

如果你有很多用户,那么计数可能会很长,并将表/索引的大部分内容加载到内存中。

如果你做了一个triger,那么你将在wrting过程中放松一些时间,因此触发的每个后续动作都会变慢。

两者之间的混合,异步提供关于追随者的统计表可能会给你最好的结果(快速写入操作,读取时极快)。

答案 2 :(得分:0)

或者,您可以使用两个数据容器:

  • 完整数据的规范化数据库,您希望显示完整的配置文件数据时阅读
  • 具有最常显示数据的搜索索引(例如Solr / Lucene),包括用于快速显示和搜索的聚合,如计数