我在PostgresQL中有一个非常大的数据库表和一个像“复制”的列。每一个新的行开始uncopied,并将在后来通过后台程序复制到另一个东西。在该表“btree(ID)WHERE replicated = 0”上有部分索引。后台程序为最多2000个条目(LIMIT 2000)进行选择,对它们进行处理,然后使用2000个准备好的sql-commands在一个事务中提交更改。更新非常大的PostgreSQL数据库表有效
现在的问题是,我想给用户一个选项来重置此复制值,使其全部为零。
更新表set replicated = 0;
是不可能的:
- 这需要非常多的时间
- 它只是重复,因为MVCC
- 它是在一个事务中所做的TABEL的大小:它要么失败或经历。
我实际上并不需要这种情况下的事务功能:如果系统关闭,它只会处理它的一部分。
其他几个问题: 做一个
update set replicated=0 where id >10000 and id<20000
也很糟糕:它顺序扫描遍布整个表是太慢了。 如果没有这样做,它仍然会很慢,因为它会是太多的寻求。
我真正需要的是一种经历所有行的方式,改变它们而不是绑定到一个巨型事务。
奇怪的是,一个
UPDATE table
SET replicated=0
WHERE ID in (SELECT id from table WHERE replicated= LIMIT 10000)
也慢,但它应该是一件好事:通过磁盘顺序表去...
(注意,在这种情况下,也有涵盖这一变化的指数)
(如MySQL的更新限制是对PostgreSQL不可用)
BTW:真正的问题是比较复杂的,我们正在谈论的是这里已经部署了嵌入式系统,所以远程模式更改很困难,但是可能的不幸的是,它可能是PostgresQL 7.4。
我在说的行数是90000000.数据库的大小可以是几千兆字节。
数据库本身只包含5个表,其中一个是非常大的表。 但这并不是坏设计,因为这些嵌入式盒子只能用一种实体操作,它不是ERP系统或类似的东西!
任何想法?
这是一个非常好的主意,虽然它不幸需要架构更改(长期更新过程)。 我真的很喜欢这种方法,实际上,当前的部分索引在内部非常类似于这个想法!只有更灵活和可管理。 – Christian 2008-09-21 21:52:42