Eva*_*oll 5 postgresql performance join execution-plan postgresql-9.5 postgresql-performance
在这个答案中,我解释了 SQL-89 的隐式语法。
但是我在玩的时候注意到不同的查询计划:
EXPLAIN ANALYZE
SELECT *
FROM (values(1)) AS t(x), (values(2)) AS g(y);
QUERY PLAN
------------------------------------------------------------------------------------
Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
Planning time: 0.052 ms
Execution time: 0.020 ms
(3 rows)
Run Code Online (Sandbox Code Playgroud)
与此相反:
EXPLAIN ANALYZE
SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(2)) AS g(y);
QUERY PLAN
------------------------------------------------------------------------------------------------
Subquery Scan on g (cost=0.00..0.02 rows=1 width=4) (actual time=0.004..0.005 rows=1 loops=1)
-> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
Planning time: 0.075 ms
Execution time: 0.027 ms
(4 rows)
Run Code Online (Sandbox Code Playgroud)
为什么其中之一会显示Subquery Scan?
隐式语法不是重写为与显式语法相同吗?
Erw*_*ter 10
隐式语法不是重写为与显式语法相同吗?
不必要。您建立在稍微不正确的假设上。就像我在参考问题下解释的那样:
FROM列表中逗号分隔的项目与显式符号几乎相同,但并不完全相同CROSS JOIN。显式连接绑定更强。在某些情况下,查询计划器必须以不同的方式处理这两种情况。
显然,规划器足够聪明,能够VALUES使用简化的计划处理具有单行表达式的表达式。我们看到VALUES表达式中不止一行的更复杂的计划:
EXPLAIN ANALYZE
SELECT *
FROM (VALUES (1), (2)) t(x)
, (VALUES (2), (3)) g(y);
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)Nested Loop (cost=0.00..0.11 rows=4 width=8) (actual time=0.059..0.064 rows=4 loops=1) -> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=4) (actual time=0.004..0.004 rows=2 loops=1) -> Materialize (cost=0.00..0.04 rows=2 width=4) (actual time=0.025..0.026 rows=2 loops=2) -> Values Scan on "*VALUES*_1" (cost=0.00..0.03 rows=2 width=4) (actual time=0.001..0.002 rows=2 loops=1)
对于VALUES用逗号分隔的表达式,简化查询计划更容易。当受显式连接约束时,Postgres 需要在与其他逗号分隔FROM项组合之前考虑连接条件。我希望我们在这种情况下看到的“subqery scan”是这种情况下更复杂的代码路径的(完全无害的)副作用。