0

我正在查看一个相当大的数据库。假设我在产品记录上有一个导出标志。
如果我想估计标志设置为 false 的产品数量,我可以调用类似 Product.where(:exported => false).count.. 的调用。

我遇到的问题是即使计数也需要很长时间,因为正在写入 100 万个产品的表。更具体地说,出口正在发生,我有兴趣计算的价值在不断变化。

所以我想在桌子上做一个脏读……不是总是脏读。而且我 100% 不希望在此连接上对数据库的所有后续调用都是脏的。
但是对于这个电话,脏是我想要的。

哦.. 我应该提到 ruby​​ 1.9.3 heroku 和 postgresql。

现在..如果我错过了另一种计数的方法,我会很高兴尝试一下。

哦,鼻涕最后一件事..这个例子是人为的。

4

2 回答 2

2

PostgreSQL 不支持脏读。

您可能希望使用触发器来维护计数的具体化视图 - 但这样做意味着一次只有一个事务可以插入产品,因为它们将争夺汇总表中产品计数的锁定。

或者,使用系统统计数据来获得快速近似值

或者,在 PostgreSQL 9.2 及更高版本上,确保有一个主键(因此有一个唯一索引)并确保真空定期运行。然后您应该能够进行相当快的计数,因为 PostgreSQL 应该选择对主键进行仅索引扫描。

请注意,即使 Pg确实支持脏读,读仍然不会返回完美的最新结果,因为在顺序扫描中,行有时会插入读指针后面。获得完美最新计数的唯一方法是防止并发插入LOCK TABLE thetable IN EXCLUSIVE MODE

于 2014-03-19T01:08:31.510 回答
0

一旦查询开始执行,它就会针对冻结的只读状态,因为这就是MVCC的全部意义所在。该快照中的值不会更改,只会在对该状态的后续修改中更改。您的查询是否需要一个小时才能运行并不重要,它正在对时间锁定的数据进行操作。

如果您的查询花费了很长时间,听起来您需要在exported列上建立索引,或者在条件中使用任何值,因为COUNT对于索引列通常非常快。

于 2014-03-18T23:34:28.453 回答