この記事では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処理の高速化を図ることができます。