【发布时间】: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