【问题标题】:Postgres - Is there a faster way to update a table with information from another DB?Postgres - 是否有更快的方法来使用来自另一个数据库的信息更新表?
【发布时间】:2012-06-02 10:39:27
【问题描述】:

我正在更新一个名为 Recipes 的表,并将 ImageUrl 列设置为 VIEW 中的匹配行。我的 UPDATE 语句是:

UPDATE Recipes R
  SET ImageUrl=L.ImageUrl
  FROM Link.Recipes L
  WHERE L.RecipeId=R.RecipeId AND L.ImageUrl is not null;

Link.Recipes 是一个 VIEW,它从不同服务器上的另一个数据库返回所有 Recipes 行,所以它已经很慢了:

查询成功返回:8541 行受影响,173236 毫秒执行 时间。

我想看看有没有办法让它更快一点。涉及具有相似行数的相同视图的 INSERT 语句要快得多,所以这里发生了一些不同的事情。

RecipeId 上当然有一个索引,但是ImageUrl 在这两个表中都没有索引。有没有更好的方法可以编写不需要将近 3 分钟的 UPDATE 语句?

说明:

'Update  (cost=0.00..4136.54 rows=995 width=1531)'
'  ->  Nested Loop  (cost=0.00..4136.54 rows=995 width=1531)'
'        ->  Function Scan on dblink t1  (cost=0.00..10.00 rows=995 width=266)'
'              Filter: (imageurl IS NOT NULL)'
'        ->  Index Scan using recipes_pkey on recipes r  (cost=0.00..4.13 rows=1 width=1281)'
'              Index Cond: (r.recipeid = t1.recipeid)'

解释分析:

'Update  (cost=0.00..4233.18 rows=995 width=1532) (actual time=168887.016..168887.016 rows=0 loops=1)'
'  ->  Nested Loop  (cost=0.00..4233.18 rows=995 width=1532) (actual time=23689.440..24500.006 rows=8549 loops=1)'
'        ->  Function Scan on dblink t1  (cost=0.00..10.00 rows=995 width=266) (actual time=23689.250..23749.288 rows=8550 loops=1)'
'              Filter: (imageurl IS NOT NULL)'
'        ->  Index Scan using recipes_pkey on recipes r  (cost=0.00..4.23 rows=1 width=1282) (actual time=0.083..0.085 rows=1 loops=8550)'
'              Index Cond: (r.recipeid = t1.recipeid)'
'Trigger trg_recipes_searchupdate: time=3808.617 calls=8549'
'Total runtime: 168889.272 ms'

【问题讨论】:

  • 视图正在使用 dblink,由于额外的数据库连接,速度要慢得多。您能否向我们展示 EXPLAIN ANALYZE 的结果?这会告诉你时间都花在了哪里。
  • @FrankHeikens - 同意。但是,我想知道为什么它比 INSERT INTO Recipes SELECT * FROM Link.Recipes; 慢得多
  • @FrankHeikens - 添加了解释分析
  • 触发器在做什么?它使用了 8549 次并且速度很慢。 dblink 是另一个瓶颈,你真的需要它吗?
  • @FrankHeikens - 触发器正在更新 tsvector 列,用于全文搜索。我绝对不需要在每一行上运行它,我可以在最后更新所有行。好收获!

标签: sql postgresql postgresql-9.1


【解决方案1】:

可能值得在 imageurl 上创建一个不为空的部分索引。在此处阅读更多信息:http://www.postgresql.org/docs/current/static/indexes-partial.html

【讨论】:

  • 另外,Recipe 中有多少行?解释计划是什么样的?
  • 我可以用远程表上的部分索引再试一次。我还添加了解释。两个食谱表都有大约 10,000 行。
  • 我很好奇索引是否会有所帮助。 VIEW 只是调用 DBLink 函数,该函数从远程表执行 SELECT *。由于 VIEW 没有索引,远程表上的索引可能甚至不会被使用,对吧?
  • 不,我不希望它在这种情况下被使用。是否值得创建一个远程过滤 imageurl 的不同视图?
  • 是的,可能会这样做,但是我想让这个查询足够灵活以更新任何一列或多列。我实际上只是删除了 WHERE 子句,它只是稍微快一点。我认为花费的大部分时间只是通过网络发送数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多