あなたの発言は私にはまったく問題ないように思えます。
最適化タスクでは、パターンを考えないでください。(not) exists
「悪くて遅い、(not) in
超クールで速い」などと考えないでください。
データベースは各ステップでどのくらいの作業を行い、それをどのように測定できるでしょうか?
簡単な例:
- ありませんで:
23:59:41 HR@sandbox> alter system flush buffer_cache;
System altered.
Elapsed: 00:00:00.03
23:59:43 HR@sandbox> set autotrace traceonly explain statistics
23:59:49 HR@sandbox> select country_id from countries where country_id not in (select country_id from locations);
11 rows selected.
Elapsed: 00:00:00.02
Execution Plan
----------------------------------------------------------
Plan hash value: 1748518851
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 4 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | NESTED LOOPS ANTI SNA| | 11 | 66 | 4 (75)| 00:00:01 |
| 3 | INDEX FULL SCAN | COUNTRY_C_ID_PK | 25 | 75 | 1 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | LOC_COUNTRY_IX | 13 | 39 | 0 (0)| 00:00:01 |
|* 5 | TABLE ACCESS FULL | LOCATIONS | 1 | 3 | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter( NOT EXISTS (SELECT 0 FROM "LOCATIONS" "LOCATIONS" WHERE
"COUNTRY_ID" IS NULL))
4 - access("COUNTRY_ID"="COUNTRY_ID")
5 - filter("COUNTRY_ID" IS NULL)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
11 consistent gets
8 physical reads
0 redo size
446 bytes sent via SQL*Net to client
363 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
11 rows processed
- 存在しません
23:59:57 HR@sandbox> alter system flush buffer_cache;
System altered.
Elapsed: 00:00:00.17
00:00:02 HR@sandbox> select country_id from countries c where not exists (select 1 from locations l where l.country_id = c.country_id );
11 rows selected.
Elapsed: 00:00:00.30
Execution Plan
----------------------------------------------------------
Plan hash value: 840074837
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 66 | 1 (0)| 00:00:01 |
| 1 | NESTED LOOPS ANTI| | 11 | 66 | 1 (0)| 00:00:01 |
| 2 | INDEX FULL SCAN | COUNTRY_C_ID_PK | 25 | 75 | 1 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN| LOC_COUNTRY_IX | 13 | 39 | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("L"."COUNTRY_ID"="C"."COUNTRY_ID")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
2 physical reads
0 redo size
446 bytes sent via SQL*Net to client
363 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
11 rows processed
この例では、NOT IN で 2 倍のデータベース ブロックを読み取り、より複雑なフィルタリングを実行します。