2009-08-19 68 views
1

作为一种粗略的猜测优化方法,我工作中的开瓶器(几年前)将我们的comments表中的body列移至次表comment_extensions表中。每次我们想要显示评论时,加入一个加入似乎都不明智,所以我会尝试将该列移回到我们的comments表中并运行一些基准测试。PostgreSQL:什么是更新3m记录的有效方法?

我的问题是此更新抓取。我让它跑了一个小时,然后关掉它,担心这会花一整晚。

UPDATE comments SET body = comment_extensions.body 
       FROM comment_extensions 
       WHERE comments.id = comment_extensions.comment_id; 

这是一个PostgreSQL 8.1数据库,并且comment_extensions.comment_id被索引。

任何建议让这个运行更快?

回答

2

这个怎么样?

http://www.postgresql.org/docs/8.1/interactive/sql-createtableas.html

CREATE TABLE joined_comments 
    AS SELECT c.id, c.author, c.blablabla, ce.body 
    FROM comments c LEFT JOIN comment_extensions ce 
    ON c.id = ce.comment_id; 

这将创建一个新的joined_comments表。这可能已经足够了(你需要重新创建索引等),但我记得Postgres 8.1有一个关于串行列创建方式的问题(抱歉找不到链接)。

所以我的建议是,你有这个新的联接表后,你复制到来自该joined_comments表的二进制文件,创建一个新的评论表,说明该ID是从一开始的序列权利,然后从该COPY BINARY文件添加到新评论表中。然后,重新创建索引。

2

那么,对于学术问题,为什么这是不明智的?查找的百分比涉及需要知道评论信息?

我的建议:小批量更新(每次10,000行?)。它可能还需要一整晚。根据系统的性质,您可能还必须实施切换逻辑,以防止系统在此迁移过程中更新或从您的扩展表中拔出。

大型数据库像这样受伤;)

+0

每当我们显示评论时,我们都需要在评论文本的'comment_extensions'表中对应的记录。所以这是100%的时间。似乎没有必要在两张桌子上应该有一张桌子。 感谢您对小批量的建议。如果我们这样做的话,我们可以在迁移过程中保持网站的流畅。 – user57995 2009-08-19 18:15:16

+0

是的,这听起来像一个负面的“优化”。检查主表中的注释字段。如果主表的注释为空,请在扩展表中检查注释。将所有新注释插入主表中。这将保持你的网站,直到你准备好转储扩展表。小批量更新(取决于您的站点的负载,10k可能太多)会让系统在后台进行迁移时执行其生产工作。 – 2009-08-19 20:01:36

1

在执行此操作时禁用日志可能会使您受益匪浅。如果它是非生产表中的测试,那么您可能不需要日志文件为您提供的保护。

如果comments.body上有一个索引或关键字,则在更新之前将其删除并在之后重新创建。

是comments.body字段固定宽度字符(N)还是它是一个varchar? Varchar过去比char()慢,我怀疑它仍然是。所以使用char not varchar。

如果您选择将数据合并到数据文件(例如引用的csv)并编写脚本将其转换为INSERTS,然后清空注释表并使用插入可能比查询更快的INSERTS加载它你有,尽管comments.id上的索引正在帮助速度。

无论如何,3e6记录都需要一些时间。

相关问题