SQL左結合クエリは、左テーブルのON column = constant
述語を無視します。ただし、右側のテーブルの別の述語を
気にします。ON column = constant
代わりに左側のテーブルON column = constant
を WHERE 句に移動すると、クエリは意図したとおりに機能します。
column = constant
左側のテーブルで、クエリの WHERE 部分またはクエリの JOIN ... ON 部分にを配置すると、なぜ問題になるのでしょうか?
(何が起こるかというと、左側のテーブルON column = constant
条件が「JOIN フィルター」ステップにプッシュされ、無視されているように見えます。)
詳細:
EXPLAIN ANALYZE
select * from DW1_PAGE_PATHS t left join DW1_PAGES g
on t.TENANT = g.TENANT
and t.PAGE_ID = g.GUID
and g.GUID = 'abcdefg' -- works
and t.CANONICAL = 'C' -- "ignored", unless moved to `where` clause
where t.TENANT = '72'
and PARENT_FOLDER like '/%';
ここ(下)は実行計画です。t.CANONICAL = 'C'
「結合フィルター」ステップまでプッシュされていることに注意してください。一方、g.GUID = 'abcdefg'
フィルターは、右側のテーブルがスキャンされているときに直接発生します。
Nested Loop Left Join (cost=... actual time=...)
Join Filter: (((t.canonical)::text = 'C'::text)
AND ((t.tenant)::text = (g.tenant)::text)
AND ((t.page_id)::text = (g.guid)::text))
-> Seq Scan on dw1_page_paths t
Filter: (((parent_folder)::text ~~ '/%'::text)
AND ((tenant)::text = '72'::text))
-> Seq Scan on dw1_pages g
Filter: (((tenant)::text = '72'::text)
AND ((guid)::text = 'abcdefg'::text))
(別の質問: t.canonical = 'C'を指定した "結合フィルター" が、 canonicalが 'C' ではない行を除外しないのはなぜですか? そうではありません。)
(PostgreSQL のバージョンpsql (9.1.6, server 9.1.1)
。)
同様のクエリへのリンクを次に示しますが、代わりに左のテーブルを句に
移動した場合に機能する理由が回答で説明されていません: Add condition while using LEFT OUTER JOINON column = constant
where