2017-09-02 3 views
0

SQL Serverデータベースを使用して、私はいくつかのSQLコードをユニオンでいくつかのテーブルからフェッチしようとしています。SQL Serverクエリは、より大きいユニオンとビューの列で話しています

新しい要件は、ビューから読み取る既存のSQL文に列を追加することです。私は個々のSQL文を実行しました。新しい列を追加した後も元のSQL文より少し長く話していて、うまく動作しています。

すべてのSQL文を共用体と一緒に実行しようとすると、永遠に実行されます。

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 1 and condn 2 

union 

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 3 and condn 4 

union 

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 5 and condn 6 

このクエリを最適化するためのアドバイスはありますか?

+3

これはクエリーではありません...疑似コードです...「X、Y、Zから」は、3ウェイデカルト積のansii 89構文です。それだけで、恐ろしく実行する必要があります。その上に、相関サブクエリ "(SELECT Col 5 from view1 ..."は外部クエリのすべての行に対して1回実行されます...そして、それを3回実行します。あなたがUNION ALLを使用しているのではなく、UNION ALLを使用しているという事実が、あなたがミックスに別の操作を追加したことを意味します。 –

+1

[古い蹴る悪い習慣スタイルのジョイン](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins.aspx) - その古いスタイルの*カンマANSI - ** 92 ** SQL標準(** 25 years ** ago)でテーブル*のスタイルのリストを*適切な* ANSI 'JOIN'構文に置き換え、その使用はお勧めしません –

+0

ありがとうございます。結合から使用するように変更します。newcol1を???に変更してよりうまく動作させるにはどうすればよいですか?上記を使用して、必要な結果を得ることはできますが、パフォーマンスは悪いです。 – user3761541

答えて

1

多くの人が見落としていることの1つは、UNIONはサブクエリのすべての行の和集合を返すだけでなく、重複をチェックしてクエリを大幅に遅くする可能性があるということです。重複を含む3つのサブクエリのすべての結果を返す場合は、通常ははるかに高速なUNION ALLを使用する必要があります。あなたが得るUNIONを使用して

Query 1 Query 2 Query 3 
------- ------- ------- 
1, 1, 1 1, 1, 1 4, 5, 6 
2, 2, 2 3, 3, 3 7, 8, 9 
1, 2, 3 3, 2, 1 1, 2, 3 
3, 2, 1    3, 2, 1 

:たとえば

、あなたはこれらの個々のサブクエリからの結果を得たとし

1, 1, 1 
2, 2, 2 
1, 2, 3 
3, 2, 1 
3, 3, 3 
4, 5, 6 
7, 8, 9 

UNION ALLを使用してあなたが得る:

1, 1, 1 
2, 2, 2 
1, 2, 3 
3, 2, 1 
1, 1, 1 
3, 3, 3 
3, 2, 1 
4, 5, 6 
7, 8, 9 
1, 2, 3 
3, 2, 1 

本当にクエリが必要な場合は、distin ct行を削除するには、クエリによって返された列にインデックスを追加する必要があります。現在のクエリはSQL Serverによって作成された自動インデックスに依存しています。

1

は、私は、全体の問合せをリライトすることをお勧め:

SELECT col 1, col 2, col3, 
    case 
     when v.col5 = 'ee' 
      then 'xx' 
      else 'yy' end as newcol1 
FROM X 
INNER JOIN Y ON Y.??? = X.??? 
INNER JOIN Z ON Z.??? = X.??? 
LEFT OUTER JOIN view1 v ON v.id = X.id AND col5 = 'ee' 
WHERE (condn 1 and condn 2) 
    OR (condn 3 and condn 3) 
    OR (condn 5 and condn 6) 

この方法では、テーブルXは、Yは、Zは一度だけ読まれる必要があります。

関連する問題