我的工作中的一个dumbveloper(多年前)将body
列从我们的comments
表移动到辅助comment_extensions
表,作为某种粗略的猜测优化。每次我们想要显示注释时进行连接似乎都是不明智的,所以我将尝试将该列移回我们的comments
表并运行一些基准测试。
我的问题是此更新抓取了。我让它运行了一个小时才把它关掉,担心它需要整晚。
UPDATE comments SET body = comment_extensions.body
FROM comment_extensions
WHERE comments.id = comment_extensions.comment_id;
这是一个PostgreSQL 8.1数据库,comment_extensions.comment_id
被编入索引。
有什么建议可以让它更快地运行?
答案 0 :(得分:2)
那么,对于一个学术问题,为什么这是不明智的?查找的百分比涉及需要知道评论信息?
我的建议:小批量更新(一次10,000行?)。它可能仍然需要整晚。根据系统的性质,您可能还必须实施切换逻辑,以防止系统在迁移期间更新或从扩展表中提取。
大型数据库像这样受伤;)
答案 1 :(得分: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有一个关于串行列创建方式的错误(抱歉无法找到链接)。
所以我的建议是,在你有了这个新的连接表之后,然后你从join_comments表中复制到一个BINARY文件,创建一个新的注释表,说明id从一开始就是一个SERIAL,然后从那个BINARY复制将文件发送到新的评论表。然后,重新创建索引。
答案 2 :(得分:1)
执行此操作时,您可能会从禁用日志中获得一些好处。如果它是非生产表中的测试,您可能不需要日志文件提供的保护。
如果comments.body上有索引或键,则在更新之前删除它,然后重新创建它。
comments.body字段是固定宽度的char(N)还是varchar? Varchar曾经比char()慢,我怀疑它仍然是。所以使用char not varchar。
如果你选择将数据合并到数据文件(例如,引用csv)并编写脚本将其转换为INSERTS,那么清空注释表并使用可能比查询更快的INSERTS加载它虽然comments.id上的索引有助于提高速度。
3e6记录无论如何都需要一段时间。