我正在查看一个相当大的数据库..让我们说我的产品记录中有一个导出的标志 如果我想估计我有多少产品,并将标志设置为false,我可以拨打这样的电话 Product.where(:exported => false).count ..。
我遇到的问题是计数需要很长时间,因为正在写入100万个产品的表。更具体地说,出口正在发生,我对计数感兴趣的价值正在发生变化。
所以我想在桌子上做一个脏读...总是不是脏读。并且我100%不希望此连接上对数据库的所有后续调用都是脏的 但对于这一次电话会议,脏话就是我想要的。
哦..我应该提到ruby 1.9.3 heroku和postgresql。
现在..如果我错过了另一种计算方法,我会很高兴尝试这一点。
OH SNOT最后一件事......这个例子是人为的。
答案 0 :(得分:2)
PostgreSQL不支持脏读。
您可能希望使用触发器来维护计数的物化视图 - 但这样做意味着一次只能有一个事务可以插入产品,因为它们会在摘要中争夺产品计数的锁定表
或者,use system statistics to get a fast approximation。
或者,在PostgreSQL 9.2及更高版本上,确保有一个主键(因而是唯一索引),并确保真空定期运行。那么你应该能够快速计算,因为PostgreSQL应该在主键上选择仅索引扫描。
请注意,即使Pg 支持脏读操作,读取仍然无法完全返回最新结果,因为行有时会在顺序中插入后面的读取指针扫描。获得完全最新计数的唯一方法是防止并发插入:LOCK TABLE thetable IN EXCLUSIVE MODE
。
答案 1 :(得分:0)
一旦查询开始执行它就会对抗冻结的只读状态,因为MVCC就是这样的。该快照中的值不会更改,仅在该状态的后续修订中。如果您的查询需要一个小时才能运行,那么它无关紧要,它会对锁定的数据进行操作。
如果您的查询需要很长时间,则表明您需要在exported
列上添加索引,或者在条件中使用的任何值,因为针对索引列的COUNT
是通常很快。