sql >> データベース >  >> RDS >> Oracle

MINUSを使用する代わりに、Oracleで2つのカーソルを比較する

    MINUSは、2番目のクエリの結果を最初のクエリから取り除くだけでなく、最初のセットに表示される場合は重複を削除するセット操作です。そのため、表示されるクエリは常に完全な結果セットを作成する必要があります。 TABLE_1からユーザーに返す前に。

    最初のセットでtrimemdヘッド/発効日の重複がないことを確認できる場合(またはそのような重複を削除したくない場合)、試すことができます

    SELECT  RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE,
        FROM   TABLE_1 A
        WHERE  A.TYPE_OF_ACTION='6'
        AND    A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15)
        AND NOT EXISTS 
             (select 1 from table_2 b 
              where RTRIM(LTRIM(b.head)) = RTRIM(LTRIM(a.head))
              and b.effective_date = a.effective_date) )
    

    そうすることで、特にtable_2が非常に小さい場合や、effective_dateまたはheadのインデックスを介して行にアクセスできる場合に、クエリが結果をより早く返し始めることができます。

    PS。可能であれば、RTRIM(LTRIM())ビットを削除してください。

    PPS。 8秒以内に戻るという保証はまだありません。これは、table_1の大きさ、およびtype_of_actionやeffective_dateのインデックスによって異なります。

    追加:

    カーソルを合わせることができます

    SELECT  RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE,
        FROM   TABLE_1 A
        WHERE  A.TYPE_OF_ACTION='6'
        AND    A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15)
    

    返された場合は行を無視します

        select 1 from table_2 b 
          where RTRIM(LTRIM(b.head)) = :1
          and b.effective_date = :1
          and rownum =1
    

    しかし、完全に実行するには確かに時間がかかります。各table_2チェックにかかる時間によっては、おそらく桁違いに長くなります(つまり、時間)。カットオフに使用される基準(呼び出しの期間または開いているSQLカーソルの期間)が正確にわからないため、外側のカーソルが閉じる可能性があります。また、table_1のサイズ/インデックス/コンテンツによっては、外側のカーソルが時間枠内の最初の行を返さない場合があります。

    table_1、table_2の行数と、使用可能なインデックスは何ですか?



    1. SQLDeveloperのCSV…

    2. 単一の制約が失敗したときにトランザクション全体を中止しないようにPostgreSQLに指示するにはどうすればよいですか?

    3. TO_CHARが数値の先頭にスペース(1つの白い文字)を追加するのはなぜですか?

    4. PostgreSQL-トランザクションブロック外のコードからVACUUMを実行する方法は?