以下のこのクエリ:
クエリ 1:
SELECT * FROM DUAL
以下と同等であり、同じ結果を生成します。
クエリ 2:
SELECT * FROM DUAL
UNION
SELECT * FROM DUAL
これは、2 つのクエリを実行する前に見るだけで明らかです。
ただし、Oracle はこの非常に単純な事実を理解していないようで、2 つの異なる計画を生成します。
プラン 1:
Execution Plan
----------------------------------------------------------
Plan hash value: 272002086
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------
プラン 2:
Execution Plan
----------------------------------------------------------
Plan hash value: 646475286
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 4 | 6 (67)| 00:00:01 |
| 1 | SORT UNIQUE | | 2 | 4 | 6 (67)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------
何故ですか?UNION で処理された 2 つのブロックを単純に比較すると、 と の両方の操作を行うよりもコストがかからないのではないUNION-ALL
でしょSORT UNIQUE
うか? または、オラクルに両方のケースで同じ計画を強制的に生成させる方法、ヒントはありますか?
ありがとう!
アップデート
Tnoy の回答により、私はさらにいくつかの実験を行う必要がありました。結果は次のとおりです。 クエリがそれ自体でUNIONされている場合、より大きなクエリは元のクエリと必ずしも同等ではありません。
たとえば、test
列が 1 つしかない非常に単純なテーブルを作成し、2 つの同一の行をロードしたとします。
さて、このテーブルに対する私の最初のクエリは次のとおりです。
SELECT * FROM TEST
この結果を返します:
A
-----
2
2
私のUNION-edクエリ:
SELECT * FROM TEST
UNION
SELECT * FROM TEST
この結果を返します:
A
-----
2
これは、Oracle オプティマイザが正しいことを行っていることを意味します。
ありがとうトニー!