ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 关于NULL

关于NULL

原创 Linux操作系统 作者:lfree 时间:2007-02-13 00:00:00 0 删除 编辑

今天在优化sql语句的时候发现存在如下sql语句,像这样
select * from t where object_name='' ;

发现执行计划里面存在全表扫描,这个问题主要在与开发人员没有判断输入的条件。

自己写了一个测试例子,如下:


1。建立表以及索引:
create table t as select * from all_objects ;

create index i_t_object_name on t(object_name);

2。分析表
BEGIN
SYS.DBMS_STATS.GATHER_TABLE_STATS (
OwnName => 'SCOTT'
,TabName => 'T'
,Cascade => TRUE);
END;

3.测试:
set autotrace traceonly
select * from t where object_name='' ;

no rows selected

Execution Plan
----------------------------------------------------------
Plan hash value: 1322348184

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 128 | 0 (0)| |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| T | 44358 | 5544K| 149 (3)| 00:00:02 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(NULL IS NOT NULL)

Note
-----
- dynamic sampling used for this statement


Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
913 bytes sent via SQL*Net to client
323 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed


开始对consistent gets为0很不理解,实际上在filter上已经说明条件是NULL IS NOT NULL,
这个条件永远为假。可以这个看在输入这个条件object_name=''时,oracle将''看成NULL,
如果输入如下条件object_name=NULL或者NULL=NULL,结果也是一样的,这个也可以说明
oracle中NULL不等于NULL。要真正查找NULL要写成 select * from t where object_name
is NULL ;

在来看这个执行结果,先修改表t的object_name字段让它不为NULL(实际上建立T表时已经定义):
ALTER TABLE T MODIFY(object_name NOT NULL);

select * from t where object_name is NULL ;

执行计划的filter还是,1 - filter(NULL IS NOT NULL)。

如果修改字段属性object_name为NULL
ALTER TABLE T MODIFY(object_name NULL);

执行计划的变为1 - filter("OBJECT_NAME" IS NULL)。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/267265/viewspace-82972/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    2285
  • 访问量
    6025374