2016-05-18 14 views
1

ビューを作成しようとしましたが、 'somenumber'列が他のテーブルに存在するかどうかを示す列を作成する必要がありました。以下のコードは動作しましたが非常にゆっくりです。テーブルを(veryYugeTableからsomeNumberを選択して)宣言し、単一のレコードごとにこのクエリを送信するか、ビューをスピードアップするために他の方法を使用するのではなく、そのテーブルをチェックすることは可能ですか?Oracle 11g、 'in'クエリを高速化する方法

case 
     when someOtherTable.someNumber in(select someNumber from veryYugeTable) then 'exists' 
     else 'doesn't exist' 
end as "someColumn" 
+1

左のjoinを使用してくださいveryNugeTable on someNumber = someOtherTable.someNumber次に、casewhen節をveryYugeTableに変更します。列がnullの場合は '存在しません' else '終了' –

+0

ビューの問合せとそのExplain計画を投稿してください。問題を見ることなく、解決策を提供することは容易ではありません。 [ここ](http://stackoverflow.com/questions/34975406/how-to-describe-performance-issue-in-relational-database?answertab=active#tab-top)のヒントを参照してください。 –

答えて

0

あなたはあなたのような何かを行う場合は、スカラー副問合せのキャッシングといくつかの利益を得るかもしれませんvyt.somenumberが一意の列の場合は、and rownum = 1は不要です。また、vyt.somenumber列のインデックスを作成することをお勧めします。

0

使用を選択して句に置くのではなく、参加左:

case 
     when veryYugeTable.OtherColumn is null then 'doesn''t exist' 
     else 'exist' 
end as "someColumn" 
+0

'someNumber'がテーブル' veryYugeTable'のPK(ユニーク)でない場合、これは失敗します(= dupsを生成します) –

+0

悲しいことにsomeNumberはveryYuTableでPKではありません。 – koray

1

クエリ罰金になります。次のように声明をするとき

left join veryYugeTable on someNumber = someOtherTable.someNumber 

は、あなたのケースを調整します。 veryYugeTable.someNumberのインデックスが必要です。

あなたが試すことができますので、時々オプティマイザは、より優れた非相関のものよりも相関副問合せを処理します。

case 
    when exists 
    (
    select * 
    from veryYugeTable 
    where veryYugeTable.someNumber = someOtherTable.someNumber 
) then 'exists' 
    else 'doesn''t exist' 
end as "someColumn" 

(このクエリはあなたとまったく同じことだけでなく、オプティマイザは同じ実行に取得する必要がありますこれは必ずしも当てはまるわけではありません)。

しかし、先に述べたように、まずそのインデックスを持っていることを確認してください。

coalesce((select 'exists' 
      from veryyugetable vyt 
      where vyt.somenumber = someOtherTable.someNumber 
      and rownum = 1), 
     'doesn''t exist') somecolumn 

N.B.:

+0

ありがとうございます、インデックスはいい考えです。 – koray

関連する問題