【问题标题】:Optimizing COUNT() on MariaDB for a Statistics Table针对统计表优化 MariaDB 上的 COUNT()
【发布时间】:2016-02-05 03:31:03
【问题描述】:

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

这是我的查询:

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

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

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

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

谢谢, 蒂姆

【问题讨论】:

  • 是否有付费索引?
  • 一般经验法则:决策上下文中使用的任何字段,例如join,where,order by,应该有一个索引。更改您正在计算的确切内容几乎无关紧要 - 您正在计算总记录的一个子集,这意味着数据库必须扫描您的 where 子句匹配项。
  • 谢谢两位。看来,我在错误的字段上设置了索引。这有很大的不同!

标签: mysql sql-server perl mariadb


【解决方案1】:

将布尔“汇总”列添加到您的统计信息表中,并使其成为具有paid 的多列索引的一部分。

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

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

这还允许您在不丢失读取计数的情况下使旧的统计表行过期。

(所有这一切都假设您已经在paid 上有一个索引;如果您没有,肯定添加一个,这可能会暂时解决您的问题,但从长远来看,您可能仍然希望能够删除旧的统计记录。)

【讨论】:

  • 哇,谢谢——这是一个很棒的计划。我真的很感激这些建议。我没有关于付费的索引,只有 id,现在我想它并没有那么有用。您建议的关于长期处理行的想法非常有意义;我将在今晚实施。再次感谢!
  • 更好的是,不要添加 summarized 列。相反,请跟踪您在表格中离开的位置。 id 很可能会起作用。 (把它放在另一个表中,也许是一个微不足道的单行单列表。)否则,UPDATE ... SET summarized=1 将成为您最严重的瓶颈。
猜你喜欢
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 1970-01-01
  • 2017-09-16
  • 2021-04-06
  • 2021-08-11
相关资源
最近更新 更多