【转】Oracle索引列NULL值引发执行计划该表的测试示例

有时开发进行表结构设计,对表字段是否为空过于随意,出现诸如id1=id2,如果允许字段为空,因为Oracle中空值并不等于空值,有可能得到意料之外的结果。除此之外,最关键的是,NULL会影响oracle的执行计划。

以下为NULL影响执行计划的测试示例。

/*1.构建test表,其中create table方式建立的test表结构object_id非空*,走索引/

SELECT Count(*) FROM all_objects WHERE object_id IS NOT NULL; --41790笔
DROP TABLE test;
CREATE TABLE test AS SELECT * FROM all_objects WHERE object_id IS NOT NULL; ----41791笔
CREATE INDEX idx_test ON test(object_id);
ANALYZE TABLE test compute STATISTICS FOR TABLE FOR ALL indexes FOR ALL indexed COLUMNS;
EXPLAIN PLAN FOR SELECT Count(*) FROM test;
SELECT * FROM TABLE(dbms_xplan.display);

Plan hash value: 3508397080                                              
                                                                         
--------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     1 |    23   (5)| 00:00:01 |
|   1 |  SORT AGGREGATE       |          |     1 |            |          |
|   2 |   INDEX FAST FULL SCAN| IDX_TEST | 41791 |    23   (5)| 00:00:01 |
--------------------------------------------------------------------------

/*2.改变test表结构,使得object_id字段为NULL,并更新一笔资料为NULL*,走全表/

ALTER TABLE test MODIFY object_id NUMBER NULL;
UPDATE test SET object_id=NULL WHERE ROWNUM=1;
COMMIT;
EXPLAIN PLAN FOR SELECT Count(*) FROM test;
SELECT * FROM TABLE(dbms_xplan.display);
Plan hash value: 1950795681                                       
                                                                  
-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   135   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST | 41791 |   135   (2)| 00:00:02 |
-------------------------------------------------------------------

/*3.对SQL指令增加条件过滤NULL之资料*,走索引/

EXPLAIN PLAN FOR SELECT Count(*) FROM test WHERE object_id IS NOT NULL;
SELECT * FROM TABLE(dbms_xplan.display);
Plan hash value: 3508397080                                                      
                                                                                 
----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     1 |     4 |    23   (5)| 00:00:01 |
|   1 |  SORT AGGREGATE       |          |     1 |     4 |            |          |
|*  2 |   INDEX FAST FULL SCAN| IDX_TEST | 41791 |   163K|    23   (5)| 00:00:01 |
----------------------------------------------------------------------------------
                                                                                 
Predicate Information (identified by operation id):                              
---------------------------------------------------                              
                                                                                 
   2 - filter("OBJECT_ID" IS NOT NULL)

/*4.将上面改的那笔object_id is NULL的资料delete掉,再查看plan,依然走全表*/

DELETE FROM test WHERE object_id IS NULL;
COMMIT;
ANALYZE TABLE test compute STATISTICS FOR TABLE FOR ALL indexes FOR ALL indexed COLUMNS;
EXPLAIN PLAN FOR SELECT Count(*) FROM test;
SELECT * FROM TABLE(dbms_xplan.display);

Plan hash value: 1950795681                                       
                                                                  
-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   135   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST | 41790 |   135   (2)| 00:00:02 |
-------------------------------------------------------------------

综上,看起来,假如索引列的表结构非空,则会走索引;若索引列表结构可空,则无论是否存在null资料,都会走全表;可以用where 索引列 is not null过滤空资料,则还是会走索引。

转自:http://www.linuxidc.com/Linux/2012-09/69938.htm

时间: 2024-10-11 05:51:43

【转】Oracle索引列NULL值引发执行计划该表的测试示例的相关文章

MySQL---正确使用索引、limit分页、执行计划、慢日志查询

正确使用索引 数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效.即使建立索引,索引也不会生效: 1 - like '%xx' 2 select * from tb1 where name like '%cn'; 3 - 使用函数 4 select * from tb1 where reverse(name) = 'wupeiqi'; 5 - or 6 select * from tb1 where nid = 1 or e

Oracle学习笔记(三)----------执行计划

查看Oracle执行计划的几种方法 一.通过PL/SQL Dev工具 1.直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果.其中,Cost表示cpu的消耗,单位为n%,Cardinality表示执行的行数,等价Rows. 2.先执行 EXPLAIN PLAN FOR select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执

添加索引后SQL消耗量在执行计划中的变化

不同索引的执行效率也是不一样的,下面比较三条SQL语句在正常查询与建立普通索引与位图索引后的CPU消耗量的变化,目的为了是加强对索引的理解与运用 实验步骤: 1.创建有特点的大数据表.为了保证索引产生前后,查询效果的正确比对,应建立一个存在大量数据的测试表.这个测试表的数据来源于SYS模式下的all_objects视图,其中包括本数据库实例中的全部对象的基本描述,具体包括对象的所有者.对象名称.创建日期等信息.创建测试表的具体过程: 创建大数据表,sys用户下的all_objects表就比较适合

『ORACLE』授予hr用户查看执行计划权限

SQL>@?/sqlplus/admin/plustrce.sql [email protected] hey~J->drop role plustrace; Role dropped. [email protected] hey~J->create role plustrace; Role created. [email protected] hey~J->[email protected] hey~J->grant select on v_$sesstat to plus

SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)

本文出处:http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里. 今天来写一下统计信息对于复合索引在预估时候的计算方法和潜在问题. 本文原形来自于是个实际业务问题,某SQL在利用一个符合索引做查询的时候,发现始终会出现预估误差较大的情况, 而改变复合索引的列顺序,这个预估行数的误差会发生变化, 也就是说,Create  index idx_index1 ON T

Sql与oracle中null值的区别

原贴链接请点击: 1 null值的介绍 NULL 是数据库中特有的数据类型,当一条记录的某个列为 NULL ,则表示这个列的值是未知的.是不确定的.既然是未知的,就有无数种的可能性.因此, NULL 并不是一个确定的值. 这是 NULL 的由来.也是 NULL 的基础,所有和 NULL 相关的操作的结果都可以从 NULL 的概念推导出来. 2 oracle中的null值介绍 在不知道具体有什么数据的时候,即未知,可以用NULL, 称它为空,ORACLE中,含有空值的表列长度为零.允许任何一种数据

oracle子查询中not in后面不能为null值的理解

首先说说oracle中的null值吧. null在oracle中代表未知,表示可能有,也可能没有.任何与null值的普通运算都为null,但可以用一些函数来处理null值,oracle排序中默认null最大. 接着进入正文 这里in后面有null,能返回数据 但加了not后,就不能返回数据了 这里的in后面的句子可以理解为or拼接,即 id in (200,201,null)可以等价于id=200 or id=201or id=null, id not in (200,201,null)可以等价

【转载】oracle索引详解2

原文URL:http://justplayoop1.iteye.com/blog/1259562 一. 索引介绍 1.1  索引的创建 语法 : CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> ON <schema>.<table_name> (<column_name> | <expression> ASC | DESC,                <column_na

oracle索引类型

逻辑上: Single column 单行索引 Concatenated 多行索引 Unique  NonUnique 非 Function-based函数索引 Domain 域索引   物理上: Partitioned 分区索引 NonPartitioned 非分区索引 B-tree: Normal 正常型B树 Rever Key 反转型B树  Bitmap Oracle提供了大量索引选项.知道在给定条件下使用哪个选项对于一个应用程序的性能来说非常重要.一个错误的选择可能会引发死锁,并导致数据