この回答では、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)
これに対して:
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)
なぜそれらの1つがSubquery Scan
?
暗黙的な構文は、明示的な構文と同じになるように書き直されていませんか?
暗黙的な構文は、明示的な構文と同じになるように書き直されていませんか?
必ずしも。少し誤った仮定に基づいて構築しています。私が参照された質問の下で説明したように:
FROM
リストのカンマ区切りの項目はほとんどですが、完全ではありません同一明示的なCROSS JOIN
表記。明示的な結合はより強力にバインドします。クエリプランナーは、特定のケースで両方のケースを異なる方法で処理するを備えています。
明らかに、プランナはVALUES
式を単純化されたプランの単一行式で処理できるほど賢いです。 VALUES
式の複数行のより複雑なプランが表示されます。
EXPLAIN ANALYZE
SELECT *
FROM (VALUES (1), (2)) t(x)
, (VALUES (2), (3)) g(y);
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
項目と組み合わせる前に結合条件beforeを考慮する必要があります。このケースで発生する「サブクエリスキャン」は、このケースのより複雑なコードパスの(完全に無害な)副作用であると考えています。