我已经在这里和其他地方阅读了一些关于人们为改善MySQL / MariaDB COUNT
功能的性能而摔跤的帖子,但我还没有找到一个非常适合我的解决方案我想做。我正在尝试为文章列表生成实时更新的读取计数列表。每次访问者访问页面时,SQL数据库中的日志表都会记录通常的访问日志类型数据(IP,浏览器等)。特别感兴趣的是,我记录用户的ID(uid)并处理用户代理标记以对已知的蜘蛛(uaType)进行分类。文章本身由"付费"柱。目标是生成一个统计数据,该统计数据不会计算海报自己对页面的看法,也不包括已知的蜘蛛。
这是我的查询:
"COUNT(*) FROM uninet_log WHERE paid='1942' AND uid != '1' AND uaType != 'Spider'"
这可以很好地工作,但是在查询具有420万个日志条目的数据库时非常慢(大约1秒)。如果我在特定运行期间多次运行查询,则会为每个查询将运行时间再增加一秒。我知道我可以按paid
进行分组,然后运行一个查询,但即便如此(这需要对我的代码进行一些修改,但可以完成)我觉得查询的1秒仍然非常慢,我和#39; m担心服务器负载时的影响。
我已尝试为COUNT(*)
或COUNT(1)
切换COUNT(id)
,但这似乎无法发挥作用。
有没有人建议如何创建更好,更快的查询来实现同样的目标?我已经考虑过让后台流程定期计算统计数据并对其进行缓存,但是如果可能的话,我很乐意坚持使用实时更新信息。
谢谢, 添
答案 0 :(得分:0)
添加一个布尔值"汇总"列到统计信息表并使其成为paid
的多列索引的一部分。
然后有一个后台进程,它在摘要表(按文章)中生成/更新包含读取计数的行,并将统计表行标记为已汇总。 (虽然摘要表可能只是你的文章表。)
然后,您的实时查询会报告已汇总结果和尚未汇总的统计信息行的总和。
这也允许您使旧统计表行过期而不会丢失读取计数。
(所有这些假设您已经拥有paid
的索引;如果您没有,请务必添加一个,这可能会解决您现在的问题,但从长远来看,您可能仍然希望能够删除旧的统计记录。)