当前位置: 首页 > 面试题库 >

PostgreSQL:count()还是保留一个计数器?

陶俊晤
2023-03-14
问题内容

我有一对多关系的两个表。假设对于表格中的每一行,表格foo中可以有0或更多行bar引用foo

客户想要知道bar引用某行中有多少行foo,对于中的所有行foo

我可以使用以下查询完成此操作:

SELECT count(bar_id) FROM bar WHERE bar.foo_id = foo.foo_id;

但是,如果表foobar很大,该怎么办?假设foo有100万行,并且bar有1000万行。我们还要说,其中99%的行的引用foo计数少于1000bar行。假设客户通常一次请求大约100行foo

我应该将朴素的count()查询与外键上的索引一起使用,还是最好保留一个计数器?甚至有可能保持反击吗?bar我相信通过使用触发器上的原子增量和减量来更新计数器,我相信这是可能的,但我可能是错的。


问题答案:

也许违反直觉,您可能会发现简单的count方法会更快,除非您的工作量非常倾向于读取。

原因是计数器表的作用是序列化更新,因此foo在任何给定时间只能进行更新给定给定的一个事务。这是因为用于更新计数器的触发器的更新将锁定foo计数器表中的该条目,并且在事务回滚或提交之前不会释放该条目。

更糟糕的是,如果您的事务影响多个事务,foo而另一事务也受到影响,则您很有可能由于死锁而使其中一个事务中止。

坚持简单的计数,直到您有充分的理由进行更改为止。



 类似资料:
  • 问题内容: 如果我在很长的列表上继续调用len(),那是我在浪费时间,还是在后台保持int计数? 问题答案: 不用担心:当然,它可以节省计数,因此在列表中是一项非常便宜的操作。顺便说一句,字符串,字典和集合也是如此!

  • 这是一个检查mongoose上重复记录的函数。在这种情况下,和是唯一字段,因此,如果数据库中有同名或电子邮件的记录,则无法插入新记录: 在运行时,我在代码中发现以下错误: 这是我第一次使用async/await,所以我可能用错了方法。我的目标是按顺序运行que unique测试(findOne),如果一切正常,则保存新的寄存器。

  • 有没有一种方法可以简化或使R代码更优雅?

  • 为了降低RSS,我正在Java8上运行不同jvm选项的实验: > 用于Rss跟踪的脚本: 用于设置java进程的JVM args: 与JCMD进行差异:

  • 问题内容: 我正在考虑在用户登录时将日期存储在我的网站中,但是我不知道什么是最合乎逻辑的解决方案。 最初,我虽然使用服务器时区,然后使用服务器计算机日期和用户计算机日期之间的差异操作来管理它,但是我也考虑过使用时区和php类日期来更改它的准确性,因此: 我的问题是,最好的解决方案是保留服务器时区还是使用用户时区? 如果我使用用户时区,是否也应像示例中那样保存时区名称? 问题答案: 我建议使用服务器

  • 问题内容: 我正在尝试创建一个列(“ consec”),该列将连续计数另一个(“二进制”)中的连续值,而不使用循环。这是预期的结果: 但是这个 导致… 我看到了其他使用分组或排序的帖子,但不幸的是,我看不到如何对我有用。在此先感谢您的帮助。 问题答案: 您可以使用compare-cumsum-groupby模式(我 确实 需要解决这个问题才能编写文档),最后是: 之所以有效,是因为首先我们得到了要