在Postgres数据库,下面的两个查询相当于性能?每个人都说“联接总是比子查询更快”,但查询规划器是否将子查询优化为联合幕后?更新与子查询与加入更新 - 哪一个更好的性能
查询1:
UPDATE table_a
SET col_1 = 'a fixed value'
WHERE col_2 IN (
SELECT col_2 FROM table_b
);
解释计划:
Update on table_a (cost=0.00..9316.10 rows=1 width=827) -> Nested Loop Semi Join (cost=0.00..9316.10 rows=1 width=827) -> Seq Scan on table_a (cost=0.00..9287.20 rows=1 width=821) -> Index Scan using idx_table_b on table_b (cost=0.00..14.45 rows=1 width=14) Index Cond: (col_2 = (table_a.col_2)::numeric)
问题2:
UPDATE table_a ta
SET col_1 = 'a fixed value'
FROM table_b tb
WHERE ta.col_2 = tb.col_2;
解释计划:
Update on table_a ta (cost=0.00..9301.67 rows=1 width=827) -> Nested Loop (cost=0.00..9301.67 rows=1 width=827) -> Seq Scan on table_a ta (cost=0.00..9287.20 rows=1 width=821) -> Index Scan using idx_table_b on table_b tb (cost=0.00..14.45 rows=1 width=14) Index Cond: (col_2 = (ta.col_2)::numeric)
我相信他们是在结果当量(请提醒我,如果我错了)。我已经尝试了几个解释计划具有大量的数据集。看起来它们在性能上是等价的,无论是在更新整个表格时还是将table_a.col_2
限制为一个小子集时。
我想确定我不会错过什么。如果它们相同,你会选择哪一个?为什么?
它们在功能上是否相同?在第一种情况下,只有匹配的行将被更新,其他行将保留其值。在第二种情况下,不匹配的行将变为NULL NULL – hashbrown
@hashbrown **错误。**我刚测试它 - 非匹配的行将不会**变为NULL。您必须对第三种可能的结构感到困惑:'UPDATE table_a SET col_1 =(SELECT'固定值'FROM table_b where table_a.col_2 = table_b.col_2')'。在这个构造中,是的,不匹配的行将**变为NULL,并且col_2必须是唯一的。 – ADTC
如果你一直在看解释输出,请包括它!此外,请提供有用的表格定义和虚拟数据以匹配您的查询,所以我们不必制作这些东西。 –