一般的に、JOINを使用して行を選択する場合とEXISTS where句を使用する場合のパフォーマンスに違いはありますか?さまざまなQ&A Webサイトを検索すると、結合の方が効率的であることがわかりますが、TeradataではEXISTSの方が優れていることをずっと前に知ったことを思い出します。
これやこれのような他のSOの答えはありますが、私の質問はTeradataに固有のものです。
たとえば、同じ結果を返す次の2つのクエリについて考えてみます。
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
join MY_TARGET_TABLE x
on x.srv_accs_id=svc.srv_accs_id
group by 1
order by 1
-と-
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
where exists(
select 1
from MY_TARGET_TABLE x
where x.srv_accs_id=svc.srv_accs_id)
group by 1
order by 1
両方のテーブルのプライマリインデックス(一意)は「srv_accs_id」です。MY_BASE_TABLEはかなり大きく(2億行)、MY_TARGET_TABLEは比較的小さい(200,000行)。
EXPLAINプランには1つの重要な違いがあります。1つ目は2つのテーブルが「RowHash一致スキャンによって」結合され、2つ目は「すべての行のスキャンによって」結合されることを示しています。どちらも「すべてのAMPのJOINステップ」であり、合計推定時間は同じ(0.32秒)であると述べています。
どちらのクエリも同じように実行されます(Teradata 13.10を使用しています)。
LEFT OUTERJOINと対応するISNULLwhere句をNOTEXISTSサブクエリと比較して不一致を見つける同様の実験では、パフォーマンスの違いが示されています。
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
left outer join MY_TARGET_TABLE x
on x.srv_accs_id=svc.srv_accs_id
where x.srv_accs_id is null
group by 1
order by 1
-と-
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
where not exists(
select 1
from MY_TARGET_TABLE x
where x.srv_accs_id=svc.srv_accs_id)
group by 1
order by 1
2番目のクエリプランはより高速です(EXPLAINで説明されているように2.21秒対2.14秒)。
私の例は些細なことで違いがわかりません。コーディングガイダンスを探しています。