2013-03-25 41 views
0

我在PostgreSQL的一个表,其中包含超过10 Milions行,我想更新一个字段:优化PostgreSQL的更新

update annonce set confirmed = true; 

但查询需要较长时间来执行,我怎样才能优化这个查询?

+0

可以添加一些细节?表“看起来”是什么样的 - 什么是列,有索引吗?你正在更新整个表格还是有涉及的where子句? – gsiems 2013-03-25 17:38:52

+0

该表有一个主键,但“确认”是我现在添加的一个表的字段,并且我想将它的值指定为true。 – 2013-03-25 17:45:47

+0

另请参见:外键?看法?其他对象引用表?你能买得起独家锁吗?其他人同时工作?你能承受截断或删除?表格有多大(以MB为单位)你有足够的可用RAM来暂时保存它吗? – 2013-03-25 21:53:14

回答

3
update annonce set confirmed = true 
where not confirmed 

部分索引可以帮助:

create index index_name on annonce (confirmed) 
where not confirmed 

比全指数的部分指数将大大降低索引大小,使所有更新,删除和插入操作变得更快。

+0

为了加强其他人撰写的内容,如果未确认的记录为表格的10%或更少,则部分索引非常有用。也许你想要一个完全不同的方法,未确认的记录保存在一个单独的表中,等待确认?这是否符合业务逻辑? – 2013-03-25 20:35:10

1

如果你经常这样做,你要稍微修改此如下:

UPDATE announce 
SET confirmed = TRUE 
WHERE NOT confirmed 

此外,你应该(confirmed)创建索引。

今天,你每次都在改变整个表格,这会造成很多死行 - 基本上表格变得臃肿。使用所提出的方法,您将只为新记录创建死行,甚至会为此索引编制索引 - 速度非常快且效率高。

+2

布尔型字段上的索引(或“行数/不同值”比率过高的任何其他字段)基本上没有用处:它只会生成更多数据和开销以更新和管理表,而没有真正的好处。除非你想使用一些奇特的部分索引,但是这又取决于数据和特定情况。 – Eggplant 2013-03-25 17:45:29

+0

@Eggplant你假设这些值是均匀分布的。如果“未确认”行不超过表格的百分之几,则可以使用该索引。但这确实浪费了空间,因为部分索引会更小更快。看到我的答案。 – 2013-03-25 17:52:27

+0

我不明白为什么要添加一个索引,我只想更新我添加的字段上的数据,顺便说一句,我测试了查询,它说“查询完成”,但在我的验证数据没有更改。 – 2013-03-25 17:58:18

0

可以说

update announce set confirmed = true where confirmed = false; 

,因为它是一个布尔值。这将做两件事情你:

  1. 相比,如果10万尚未确认公告的数量较少,可以把现场变成一个索引,让PostgreSQL的使用索引以便更快地访问。

  2. 在较早版本的postgresql中,免费空间地图的大小是固定的。如果你更新了一张大桌子,那么无论你配置了多大的桌子,都会超出这张地图。因此,您必须定期执行VACUUM FULL,否则数据库使用的磁盘空间将超出您最大的想象空间。

0

你有三个答案。

他们都是错的。

没有人认为是NULL。而NULL只有这里需要考虑的事情!因为,当你在注释透露:

“证实”是,我现在加入

所有行的定义有confirmed IS NULL表的字段。 A WHERE条款根本无济于事,只需花费一点点。

即使我们不知道您刚刚添加的列,因为它在你原来的问题没有:作为NULL尚未排除,声明必须是:

UPDATE announce 
SET confirmed = TRUE 
WHERE confirmed IS DISTINCT FROM TRUE 

但这不会帮助你。相反,索引也没有。无论如何,整个表格都必须重写。有没有办法绕过它。然而,你可以做很多事情来做到这一点。

都取决于关于您没有与我们分享的表的信息。

+0

请注意,评论是在答案后发布的,所以我们假设'未确认的**行**只被添加到已包含大部分“已确认”的大表中。 – 2013-03-26 11:04:24

+0

@ClodoaldoNeto:你有没有读过*我的回答?我已经在解决这个问题。所有三个答案都是(并且仍然)*错误*首先。它们产生不正确的结果NULL值。 – 2013-03-28 04:40:48

+0

是的,我读过,我知道其他答案是错的,包括我的。我在说的是他们错了,因为他们在评论中发布之前已经发布了说明'已确认'列是在已经存在的表格中创建的。 – 2013-03-28 08:00:04