优化 MariaDB 上的 COUNT() 以获得统计数据 Table

Optimizing COUNT() on MariaDB for a Statistics Table

我在这里和其他地方阅读了很多关于人们努力提高 MySQL/MariaDB COUNT 函数性能的帖子,但我还没有找到完全适合我的解决方案我正在尝试做。我正在尝试为文章列表生成实时更新的阅读计数列表。访问者每次访问一个页面时,table数据库中的一个日志table记录了通常访问日志类型的数据(IP、浏览器等)。特别有趣的是,我记录了用户的 ID (uid) 并处理了用户代理标签以对已知蜘蛛 (uaType) 进行分类。文章本身由 "paid" 列标识。目标是生成一个统计数据,该统计数据不计算张贴者自己的页面浏览量,也不包括已知的蜘蛛程序。

这是我的查询:

"COUNT(*) FROM uninet_log WHERE paid='1942' AND uid != '1' AND uaType != 'Spider'"

这工作得很好,但在查询具有 420 万个日志条目的数据库时非常慢(大约 1 秒)。如果我在特定 运行 期间多次 运行 查询,则每次查询的 运行 时间都会增加大约一秒。我知道我可以按 paid 分组,然后 运行 一个查询,但即便如此(这需要对我的代码进行一些修改,但可以完成)我觉得查询仍然需要 1 秒真的很慢,我担心服务器负载过大时的影响。

我试过将 COUNT(*) 换成 COUNT(1)COUNT(id),但这似乎没有什么不同。

有没有人建议我如何创建更好、更快的查询来实现同样的目标?我考虑过让后台进程定期计算统计数据并缓存它们,但如果可能的话,我愿意坚持实时更新信息。

谢谢, 蒂姆

将布尔值 "summarized" 列添加到您的统计信息 table 并使其成为具有 paid 的多列索引的一部分。

然后有一个后台进程,produces/updates 行包含摘要中的阅读计数 table(按文章)并将统计信息标记为摘要 table 行。 (尽管摘要 table 可能只是您的文章 table。)

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

这还允许您使旧统计信息 table 行过期而不会丢失您的阅读计数。

(所有这些假设您已经在 paid 上有一个索引;如果您没有,一定要添加一个,这可能会暂时解决您的问题,尽管在长期 运行 中可能您仍然希望能够删除旧的统计记录。)