有时开发进行表结构设计,对表字段是否为空过于随意,出现诸如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

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

  1. 数据库 SQL :有关 NULL 值引发 TRUE、FALSE、UNKNOW 三值逻辑

    在 Java.C# 中,相信如果是 boolean 类型值,只有两种选择 true.false.然而,在 SQL 查询中,NULL 值的引入,使得新增了 UNKNOW ,因此,就产生了 TRUE.FA ...

  2. 第二百八十八节,MySQL数据库-索引、limit分页、执行计划、慢日志查询

    MySQL数据库-索引.limit分页.执行计划.慢日志查询 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获 ...

  3. 让索引包含null值的两种方法

    1. 把有NULL值的列与一个常数,或者一个带有not null约束的列一同索引 create index ind_01 on t01(col01,1); 或者 create index ind_01 ...

  4. MySQL索引对NULL值的处理

    # 索引不会包含有NULL值的列 只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的.所以我们在数据库设计时不要让字段的默认值为NU ...

  5. Oracle 与 Mysql NULL值,空字符串''的区别

    Oracle(null等同于空字符'') 1.oracle插入空字符串默认替换成null 2.oracle查询(null和被替换的空字符)时使用 is null/is not null 3.使用聚合函 ...

  6. oracle执行计划之-表连接方式

    转载自:http://blog.csdn.net/tianlesoftware/article/details/5826546 在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的 ...

  7. python全栈开发day58-mysql存储过程,权限,索引,慢日志,执行计划,分页优化处理

    1.存储过程 delimiter // create procedure insert_data(in rows int) begin DECLARE n INT DEFAULT 1; drop ta ...

  8. 看懂Oracle执行计划、表连接方式

    看懂Oracle执行计划  原文:https://www.cnblogs.com/Dreamer-1/p/6076440.html 最近一直在跟Oracle打交道,从最初的一脸懵逼到现在的略有所知,也 ...

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

    正确使用索引 数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效.即使建立索引,索引也不会生效: - like '%xx' se ...

随机推荐

  1. c# .Net :Excel NPOI导入导出操作教程之List集合的数据写到一个Excel文件并导出

    将List集合的数据写到一个Excel文件并导出示例: using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using System;using Sys ...

  2. Bash 4.4 中新增的 ${parameter@operator} 语法

    Bash 4.4 中新增了一种 ${...} 语法,长这样:${parameter@operator}.根据不同的 operator,它展开后的值可能是 parameter 这个参数的值经过某种转换后 ...

  3. 1.0、Struts2的简单搭建方法

    一.Struts2:是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet:用于jsp页面与Java代码之间的交互. 1.核心:Filter拦截器,对所有的请求进行拦截. 2.工作 ...

  4. 开放数据库互联ODBC配置(odbcconf)

    开放数据库互连(ODBC)是微软引进的一种早期数据库接口技术,通过ODBC驱动程序可访问数据库数据:使用ODBC管理器可以完成对数据库的链接操作.笔者利用ODBC接口,将WINDOWS计数器信息写入到 ...

  5. nyoj 106背包问题(贪心专题)

    背包问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w< ...

  6. [Math] 常见的几种最优化方法

    我们每个人都会在我们的生活或者工作中遇到各种各样的最优化问题,比如每个企业和个人都要考虑的一个问题“在一定成本下,如何使利润最大化”等.最优化方法是一种数学方法,它是研究在给定约束之下如何寻求某些因素 ...

  7. thinkphp3.2跨控制器调用其他模块的方法

    thinphp中前台后台都有互相调用方法,这样可以省去重复内容. 1 2 $hello = new \Admin\Common\Fun\hello(); $hello->hehe(); 调用其他 ...

  8. 【Go入门教程7】并发(goroutine,channels,Buffered Channels,Range和Close,Select,超时,runtime goroutine)

    有人把Go比作21世纪的C语言,第一是因为Go语言设计简单,第二,21世纪最重要的就是并行程序设计,而Go从语言层面就支持了并行. goroutine goroutine是Go并行设计的核心.goro ...

  9. python3 爬虫

    保存当前cookie到本地 import urllib.request as ur import http.cookiejar as hc url='http://www.xxxx.com/admin ...

  10. Html 两个DIV并排的问题

    在一个容器内部,要放在两个并排的DIV,两个方法: 1.使用浮动.这个方式div是脱离文档流的,在窗口布局复杂,大小变化的时候,可能会有一些不希望的情况发生. <!DOCTYPE HTML> ...