MINUS処理を高速化する方法

この記事ではMINUS処理を高速化する方法について解説します。

 MINUS処理の実行計画

「MINUS」演算子を使用した処理はデータの差分をチェックする際などに使用されます。

この処理の実行計画を確認してみると以下のようになります。


PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------
select * from table1 minus select * from table1
----------------------------------------------------------------------------
| Id  | Operation             | Name           | Rows  | Bytes | Time     | 
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |        |       |       |       |          |
|   1 |  MINUS                |        |       |       |       |          |
|   2 |   SORT UNIQUE         |        |   114K|   281M|   446M| 00:00:03 |
…
|   5 |      TABLE ACCESS FULL| TABLE1 |   114K|   281M|       | 00:00:01 |
|   6 |   SORT UNIQUE         |        |   114K|   281M|   446M| 00:00:03 |
…
|   9 |      TABLE ACCESS FULL| TABLE1 |   114K|   281M|       | 00:00:01 |
----------------------------------------------------------------------------

MINUS処理では「SORT UNIQUE」というオペレーションが実行されています。

これはデータ重複を排除するために内部的にソートが実行するオペレーションです。

このソート処理は時間的負荷も大きく、一時表領域を大量に消費するため、データが大量にある場合は好ましい処理ではありません。

MINUS処理ではこのソートが行われてしまうため、大量のデータを扱う場合は処理に時間がかかってしまいます。


 MINUS処理の高速化

MINUSの処理を高速化するにはSQLを書き換えることにって実現できます。

MINUSはNOT EXSITS条件とDISTINCT句に変換することができます。

下記のヒント句を使うことによって、SQL文はそのままで、内部的にSQLを置き換えてくれます。

/*+ SET_TO_JOIN(@SET$1) */


 ヒント句を使用した際の実行計画

ヒント句を使用してSQL文を実行した際の実行計画を確認してみます。

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
select /*+ SET_TO_JOIN(@SET$1) */ * from table1 minus select * table1
-------------------------------------------------------------------------------------
| Id  | Operation                            | Name      | Rows  | Bytes | Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |           |       |       |          |
|   1 |  NESTED LOOPS ANTI                   |           |   114K|   562M| 00:00:01 |
…
|   4 |     TABLE ACCESS FULL                | TABLE1    |   114K|   281M| 00:00:01 |
…
|*  7 |     TABLE ACCESS BY LOCAL INDEX ROWID| TABLE1    |     1 |  2579 |          |
|*  8 |      INDEX UNIQUE SCAN               | PK_TABLE1 |     1 |       |       |
-------------------------------------------------------------------------------------

実行計画が変わり、SORT UNIQUEのオペレーションが無くなっています。

このようにしてSQL処理の高速化を図ることができます。