在MariaDB上为统计表优化COUNT()

时间:2016-02-04 19:06:18

标签: mysql sql-server perl mariadb

我已经在这里和其他地方阅读了一些关于人们为改善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),但这似乎无法发挥作用。

有没有人建议如何创建更好,更快的查询来实现同样的目标?我已经考虑过让后台流程定期计算统计数据并对其进行缓存,但是如果可能的话,我很乐意坚持使用实时更新信息。

谢谢, 添

1 个答案:

答案 0 :(得分:0)

添加一个布尔值"汇总"列到统计信息表并使其成为paid的多列索引的一部分。

然后有一个后台进程,它在摘要表(按文章)中生成/更新包含读取计数的行,并将统计表行标记为已汇总。 (虽然摘要表可能只是你的文章表。)

然后,您的实时查询会报告已汇总结果和尚未汇总的统计信息行的总和。

这也允许您使旧统计表行过期而不会丢失读取计数。

(所有这些假设您已经拥有paid的索引;如果您没有,请务必添加一个,这可能会解决您现在的问题,但从长远来看,您可能仍然希望能够删除旧的统计记录。)