はじめに

外部結合を行っているViewに条件を付けて検索する時、結合元と結合先に条件を付けた場合では以下のような違いがあるため注意してください。

●結合元に条件が付与された場合、条件で検索された後に結合処理が行われるためデータが絞られた状態で結合処理が行われます。
●結合先に条件が付与された場合、データが絞られていない状態で結合処理が行われるため、パフォーマンスに影響を与えます。

※結合元と結合先に関しては下記図を参照してください。

以下は外部結合しているViewに条件を付けて検索する例になります。

outer_view2

結合元と結合先に条件を付けてViewを検索した際の違いを確認していきます。


1.lineorder表とpart表を外部結合するViewを作成します。
create or replace view lo_view as
select l.lo_orderdate,p.p_name,p.p_category,p.p_color,sum(l.lo_ordertotalprice) lo_ordertotalprice
from lineorder l
left join part p on l.lo_partkey = p.p_partkey
group by l.lo_orderdate,p.p_name,p.p_category,p.p_color
order by l.lo_orderdate,p.p_name,p.p_category,p.p_color
;

2.結合元のlineorder表の”lo_orderdate”に条件を付けて検索します。
select * from lo_view where lo_orderdate = 19980101;

3.実行計画を確認します。
  lineorder表を検索時に条件が付与されていることがわかります。
Access Path:
+-GROUPBY HASH (LOCAL RESEGMENT GROUPS) [Cost: 3M, Rows: 100K] (PATH ID: 3)
| Aggregates: sum(l.lo_ordertotalprice)
| Group By: l.lo_orderdate, p.p_name, p.p_category, p.p_color
| +—> JOIN HASH [LeftOuter] [Cost: 3M, Rows: 4M] (PATH ID: 4)
| | Join Cond: (l.lo_partkey = p.p_partkey)
| | Materialize at Output: l.lo_orderdate, l.lo_ordertotalprice
| | +– Outer -> STORAGE ACCESS for l [Cost: 3M, Rows: 4M] (PATH ID: 5)
| | | Projection: public.lineorder_DBD_3_rep_dbd9_node0001
| | | Materialize: l.lo_partkey
| | | Filter: (l.lo_orderdate = 19980101) ★ <=== lineorder表を検索する際に条件が付与されています
| | +– Inner -> STORAGE ACCESS for p [Cost: 13K, Rows: 1M] (PATH ID: 6)
| | | Projection: public.part_DBD_4_rep_dbd9_node0001
| | | Materialize: p.p_category, p.p_partkey, p.p_name, p.p_color

4.結合先のpart表の”p_color”に条件を付けて検索します。
select * from lo_view where p_color = ‘yellow’;

5.実行計画を確認します。
  part表を検索時に条件が付与されず結合時に付与されていることがわかります。
Access Path:
+-GROUPBY HASH (LOCAL RESEGMENT GROUPS) [Cost: 7M, Rows: 20M] (PATH ID: 3)
| Aggregates: sum(l.lo_ordertotalprice)
| Group By: l.lo_orderdate, p.p_name, p.p_category, p.p_color
| +—> JOIN HASH [LeftOuter] [Cost: 5M, Rows: 720M] (PATH ID: 4)
| | Join Cond: (l.lo_partkey = p.p_partkey)
| | Materialize at Output: l.lo_orderdate, l.lo_ordertotalprice
| | Filter: (p.p_color = ‘yellow’) ★ <=== lineorder表とpart表を結合時に条件が付与されています
| | +– Outer -> STORAGE ACCESS for l [Cost: 2M, Rows: 720M] (PATH ID: 5)
| | | Projection: public.lineorder_DBD_3_rep_dbd9_node0001
| | | Materialize: l.lo_partkey
| | +– Inner -> STORAGE ACCESS for p [Cost: 13K, Rows: 1M] (PATH ID: 6)
| | | Projection: public.part_DBD_4_rep_dbd9_node0001
| | | Materialize: p.p_category, p.p_partkey, p.p_name, p.p_color
                         ★ <=== part表を検索する際に条件が付与されていません

※実行計画の取得方法や見方に関しては下記サイトを参照してください。
「SQLの実行計画を確認する方法」
http://vertica-tech.ashisuto.co.jp/sql-plan/

対処方法

結合先のテーブルのデータを絞って結合するためには、Viewの中に条件を付ける必要があります。
create or replace view lo_view as
select l.lo_orderdate,p.p_name,p.p_category,p.p_color,sum(l.lo_ordertotalprice) lo_ordertotalprice
from lineorder l
left join part p on l.lo_partkey = p.p_partkey
where p_color = ‘yellow’ ★ <== 検索条件を付けます
group by l.lo_orderdate,p.p_name,p.p_category,p.p_color
order by l.lo_orderdate,p.p_name,p.p_category,p.p_color
;


検証バージョンについて

この記事の内容はVertica 7.2で確認しています。