web-dev-qa-db-ja.com

この暗黙の結合が明示的な結合とは異なる方法で計画されるのはなぜですか?

この回答では、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
暗黙的な構文は、明示的な構文と同じになるように書き直されていませんか?

5
Evan Carroll

暗黙的な構文は、明示的な構文と同じになるように書き直されていませんか?

必ずしも。少し誤った仮定に基づいて構築しています。私が参照された質問の下で説明したように:

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を考慮する必要があります。このケースで発生する「サブクエリスキャン」は、このケースのより複雑なコードパスの(完全に無害な)副作用であると考えています。

10