As suggested by @Phil, you can try and get Oracle to use a COUNT STOPKEY operation as follows:
testbed:
create table a as
select level x, level y, level z from dual connect by level<=1000000;
--
create table b as
select level+10 x, level+10 y, level+10 z from dual connect by level<=1000000;
count stopkey query:
select *
from( select *
from a
where not exists (select * from b where x=a.x and y=b.y and z=b.z))
where rownum<=1;
/*
RESULT
------------
Not the same
*/
plan:
Plan hash value: 322064455
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 52 | | 15244 (1)| 00:02:48 |
|* 1 | COUNT STOPKEY | | | | | | |
|* 2 | HASH JOIN ANTI | | 776K| 38M| 18M| 15244 (1)| 00:02:48 |
| 3 | TABLE ACCESS FULL| A | 776K| 9855K| | 5756 (1)| 00:01:04 |
|* 4 | TABLE ACCESS FULL| B | 1018K| 37M| | 5770 (1)| 00:01:04 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=1)
2 - access("X"="A"."X")
4 - filter("Y" IS NOT NULL AND "Z" IS NOT NULL)
Note
-----
- dynamic sampling used for this statement (level=2)
If you are very likely to hit a mis-match early, you may want to encourage the CBO to use NESTED LOOPS ANTI (perhaps you could test this with the NL_AJ hint). In the worst case this will run very slowly on big tables especially if there is no index to speed up the lookup on b, but the best case will be very quick.