暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

NULL-AWARE ANTI-JOIN

扫地僧的故事 2020-11-27
2594
我又回来了,继续更新!!
不管在Oracle还是MySQL中,NULL值好像一直是一个比较头疼的问题。
不过今天主要研究的是,Oracle中做反连接(Anti-Join)时,关联列上存在NULL值的问题。
测试数据:
    create table t1(c1 number, c2 number);
    create table t2(c1 number primary key, c2 number);
    begin
    for i in 1..100 loop
    insert into t1 values (decode(mod(i,2), 0 , null, i),i);
    insert into t2 values(i,i);
    end loop;
    end;
    /
    commit;
    复制
    测试SQL(这两个SQL不等价):
      select t1.* from t1 where c1 not in(select c1 from t2);
      select t1.* from t1 where not exists(select 1 from t2 where t1.c1=t2.c1);
      复制
      先观察下面这个执行计划,两表关联用了原始的FILTER。

      SQL_TEXT:

      以上SQL中, not in 没能使用 ANTI JOIN,而是使用了FILTER
      当语句中使用not exists,两表关联可以使用ANTI JOIN。
      继续观察下面的执行计划
      同样的SQL,此时not in语句也使用了ANTI JOIN,而不是FILTER了。
      造成执行计划差异的原因,其实是参数"_optimizer_null_aware_antijoin"。11G以后这个参数默认是打开的。
      因此,可以得出结论,如果没有NULL AWARE,not in 语句只能使用FILTER,在NULL AWARE的情况下,not in语句可以使用 ANTI JOIN
      文章转载自扫地僧的故事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论