2016-09-16 12 views
2

以下の結合句を使用すると、ストアドプロシージャ全体が非常に遅く実行されます。私は、同じテーブルから情報を収集するために共用体を使用していますが、2番目と3番目の共用体の句は、フィルタリングのために他の表にも結合します。私はこれが最良のコーディング手法ではないかもしれないと理解し、誰かがより良い構文で私を導くことを望んでいました。SQLのUNION句のパフォーマンスの問題

私はとても好きですが、各シナリオをテストするためのORを使用して、ステータステーブル上の単一のクエリとしてこれを書き換えることができると思い
select ss.int_tran_id 
from status ss 
where ss.stage in ('ACHPayment_Confirmed', 'HIFV4', 'HIFV5_FTRINF', 'Payment_HIFV5_FTRINF') 
UNION 
select ss.int_tran_id 
from status ss, references rf 
where ss.int_tran_id = rf.int_tran_id 
and ss.stage = 'PREVDAY' 
and rf.mid_ref IS NOT NULL 
UNION 
select ss.int_tran_id 
from status ss, app_data ad, ach aa 
where ss.int_tran_id = ad.int_tran_id 
and ad.app_data_id = aa.ach_id 
and ss.stage = 'PREVDAY' 
and aa.par_number IS NOT NULL 
+0

人々は何が起こっているか理解するために、あなたのインデックスを含むテーブル構造、およびクエリの実行計画を掲示し、あなたのクエリが – Aleksej

+1

を向上することができる方法をしてくださいは、明確な記録はありますか?はいの場合は、UNION ALLを使用します。実行計画が掲載されていない限り、それ以上のヒントはありません:) –

+0

そのかなり長いですが、ここに添付ファイルとして投稿できますか?そして、いいえ、レコードは区別されません – QuickDrawMcgraw

答えて

2

SELECT ss.int_tran_id 
FROM status SS 
WHERE ss.stage in ('ACHPayment_Confirmed', 'HIFV4', 'HIFV5_FTRINF', 'Payment_HIFV5_FTRINF') 
OR  (ss.stage = 'PREVDAY' 
     AND (EXISTS (SELECT NULL 
        FROM references rf 
        WHERE ss.int_tran_id = rf.int_tran_id 
        AND rf.mid_ref IS NOT NULL) 
      OR EXISTS (SELECT NULL 
         FROM app_data ad 
           INNER JOIN ach aa 
           ON (ad.app_data_id = aa.ach_id) 
         WHERE ss.int_tran_id = ad.int_tran_id 
         AND aa.par_number IS NOT NULL))); 
+1

ボネストさん、ありがとうございます。実行時間が60%減少しました。私は本当にあなたの助けに感謝します! – QuickDrawMcgraw

+0

明示的な結合を使用して変換していただきありがとうございます。誰も暗黙的な結合を使用するべきではありません。 – HLGEM

0

は、ブラケットを使用して1 SELECT(全体のクエリを書いて考えてみましょう、AND、OR)、UNIONのすべての非効率な重複チェックが削除されます。

あなたはパヴェル・DYLが示唆ALLとしてUNIONを試すことができますが、あなたはその作品を作ることができれば、あなたはおそらく1 SELECTでそれをすべてを書くことができ、これは、オプティマイザより多くのオプションを提供します。

0

私の変種:

select ss.int_tran_id 
from status ss 
left join references rf on (ss.stage = 'PREVDAY' 
          and ss.int_tran_id = rf.int_tran_id 
          and rf.mid_ref IS NOT NULL) 
left join app_data ad on (ss.stage = 'PREVDAY' 
          and ss.int_tran_id = ad.int_tran_id) 
left join ach aa on (ss.stage = 'PREVDAY' 
        and ad.app_data_id = aa.ach_id 
        and aa.par_number IS NOT NULL) 
where ss.stage in ('ACHPayment_Confirmed', 'HIFV4', 'HIFV5_FTRINF', 'Payment_HIFV5_FTRINF') 
    or rf.int_tran_id is not null 
    or aa.ach_id is not null 
+0

参照に複数の行がある場合は、余分な行を追加する可能性があります.int_tran_id/ach_idごとにapp_dataまたはachテーブルがあります。結合がすべて1-1の条件であることを絶対に確かにしていない限り、重複を削除するには特別な別名が必要です... – Boneist

関連する問題