对this answer的评论指出,反连接可能已经过优化,可以更有效地在Oracle中进行外连接。我有兴趣看看哪些解释/证据可能会支持或反驳这种说法。
答案 0 :(得分:2)
在SQL查询中使用“not exists”或“not in”时,让Oracle选择合并反连接或散列反连接访问路径。
快速解释
例如,给定表A和B之间的连接(来自Ax = Bx上的A连接B),Oracle将从表A中获取所有相关数据,并尝试将它们与表B中的相应行匹配,因此它严格依赖于表A谓词的选择性。
使用反连接优化时,Oracle可以选择具有更高选择性的表并将其与另一个表匹配,这可能会导致更快的代码。
使用常规连接或子查询无法做到这一点,因为它不能假设表A和B之间的一个匹配足以返回该行。
相关提示: HASH_AJ,MERGE_AJ。
更多
This看起来像一篇关于这个主题的精彩而详细的文章。
Here是另一篇更重要的文章。
答案 1 :(得分:0)
如果Oracle可以将left join + where null变换为ANTI join,那么它就完全一样了。
create table ttt1 as select mod(rownum,10) id from dual connect by level <= 50000;
insert into ttt1 select 10 from dual;
create table ttt2 as select mod(rownum,10) id from dual connect by level <= 50000;
select ttt1.id
from ttt1
left join ttt2
on ttt1.id = ttt2.id
where ttt2.id is null;
select * from ttt1 where id not in (select id from ttt2);
如果你看一下
Final query after transformations:******* UNPARSED QUERY IS *******
在事件10053的跟踪中,您将找到两个完全相同的查询(您可以在跟踪文件的谓词中看到&#34; =&#34;因为ANTI连接没有特殊符号)< / p>
SELECT "TTT1"."ID" "ID" FROM "TTT2" "TTT2","TTT1" "TTT1" WHERE "TTT1"."ID"="TTT2"."ID"
他们有完全相同的计划
-----------------------------------
| Id | Operation | Name |
-----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | HASH JOIN ANTI | |
| 2 | TABLE ACCESS FULL| TTT1 |
| 3 | TABLE ACCESS FULL| TTT2 |
-----------------------------------
但是,如果你提示禁用转换,那么计划将是
select --+ no_query_transformation
ttt1.id
from ttt1, ttt2
where ttt1.id = ttt2.id(+) and ttt2.id is null;
------------------------------------
| Id | Operation | Name |
------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | FILTER | |
| 2 | HASH JOIN OUTER | |
| 3 | TABLE ACCESS FULL| TTT1 |
| 4 | TABLE ACCESS FULL| TTT2 |
------------------------------------
并且性能会显着下降。
如果你将ANSI连接语法与deisabled转换一起使用,那就更糟了。
select --+ no_query_transformation
ttt1.id
from ttt1
left join ttt2
on ttt1.id = ttt2.id
where ttt2.id is null;
select * from table(dbms_xplan.display_cursor(format => 'BASIC'));
--------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | VIEW | |
| 2 | FILTER | |
| 3 | MERGE JOIN OUTER | |
| 4 | TABLE ACCESS FULL | TTT1 |
| 5 | BUFFER SORT | |
| 6 | VIEW | VW_LAT_2131DCCF |
| 7 | TABLE ACCESS FULL| TTT2 |
--------------------------------------------------
因此,简而言之,如果Oracle可以将转换应用于ANTI连接,那么性能完全相同,否则可能会更糟。您还可以使用提示&#34; - + rule&#34;禁用CBO转换并查看发生的情况。
PS。另外,SEMI连接在某些情况下可能比内连接+更好,即使启用了CBO转换也是如此。