我们知道,Oracle软件最核心的组件就是优化器,可以说他决定了一条SQL能否正确执行的路径,这两天就碰到了一个场景。
创建测试表,插入两条测试的数据,
SQL> create table t_null (id number, name varchar2(1));Table created.SQL> insert into t_null values(1, '');1 row created.SQL> insert into t_null values(2, 'a');1 row created.SQL> commit;Commit complete.SQL>ID N---------- -12 a
此时,如果按照id判断是否为空的操作,如下所示,谓词信息是id is null,
select * from t_Null where id is null;----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 15 | 3 (0)| 00:00:01 ||* 1 | TABLE ACCESS FULL| T_NULL | 1 | 15 | 3 (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------1 - filter("ID" IS NULL)
如果我们将id设置非空约束,会出现什么现象?
SQL> alter table t_Null modify id not null;Table altered.
谓词信息改成了null is not null,预估Cost=0,
select * from t_Null where id is null;-----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |-----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 15 | 0 (0) | ||* 1 | FILTER | | | | | || 2 | TABLE ACCESS FULL| T_NULL | 2 | 30 | 3 (0) | 00:00:01 |-----------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------1 - filter(NULL IS NOT NULL)
null is not null,明显是个不成立的条件,相当于此处Oracle做了一个“短路”的处理,从逻辑上说,id字段,不可能存在空值,where使用id is null就是个无意义的操作,返回肯定是空,既然如此,不需要消耗资源为了得到一个已经确定的结果,因此直接使用了这个“短路”条件,结束了这次执行。
优化器的处理,还是很具备逻辑性的,值得学习。
近期更新的文章:
《小白学习MySQL - MySQL会不会受到“高水位”的影响?》
《我的股市生涯》
《非Oracle Linux下Oracle 19c CDB数据库安装》
《案例纠正一则》
《VMWare 11安装RedHat Linux 7过程中碰到的坑》
文章分类和索引:
文章转载自bisal的个人杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




