OpenText Analytics Database 旧Vertica

技術情報サイト

Analytics Database

外部結合を行っているViewに条件を付けて検索する際の注意点

公開日:
更新日:
アーキテクチャ
#結合
#View

外部結合を行っている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.<strong>lineorder</strong>_DBD_3_rep_dbd9_node0001
 | | | Materialize: l.lo_partkey
 | | | Filter: (l.lo_orderdate = 19980101) <strong>★ <=== lineorder表を検索する際に条件が付与されています</strong>
 | | +– 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’) <strong>★ <=== lineorder表とpart表を結合時に条件が付与されています</strong>
 | | +– 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.<strong>part</strong>_DBD_4_rep_dbd9_node0001
 | | | Materialize: p.p_category, p.p_partkey, p.p_name, p.p_color
                          <strong>★ <=== part表を検索する際に条件が付与されていません</strong>

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

対処方法

結合先のテーブルのデータを絞って結合するためには、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 9.2で確認しています。

更新履歴

2019/04/22 検証バージョンを9.2に変更
2016/04/14 本記事を公開