oracle null值应用索引
来源:互联网 发布:淘宝alexa 编辑:程序博客网 时间:2024/06/05 03:37
oracle null值应用索引
大家都知道,oracle不会空值null建立索引,因此在通过含有null值的条件检索数据时,将不会应用表上已有的索引。
但是有两种方法可以避免这样的情况
1、建立复合索引
2、建立nvl函数索引
先说第一种情况:建立复合索引
SQL> set autotrace traceonly;
--先建立一张测试表
SQL> create table test_f (id number,no number);
Table created.
SQL> begin
2 for i in 1..1000 loop
3 insert into test_f values(i,i);
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
在表列no上建议一个索引
SQL> create index test_f_a on test_f(no);
Index created.
对表进行分析
SQL> exec dbMs_stats.gather_table_statS('SYS','TEST_F',CASCADE=>TRUE);
PL/SQL procedure successfully completed.
现在用no列上附加条件no is null 查看执行计划:
SQL> select * from test_f where no is null;no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 3687589707
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TEST_F | 1 | 8 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("NO" IS NULL)
Statistics
----------------------------------------------------------
10 recursive calls
0 db block gets
22 consistent gets
0 physical reads
0 redo size
394 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
0 rows processed
---发现尽管no列上有索引,也已经对表进行了分析,但是依然走的全表扫描。no is null不能应用该列上的索引。
---删除该索引,建立一个复合索引。SQL> drop index test_f_a;
Index dropped.
SQL> create index test_f_a on test_f(no,0);
Index created.
SQL> exec dbms_stats.gather_table_stats('SYS','TEST_F',CASCADE=>TRUE);
PL/SQL procedure successfully completed.
--现在再执行刚才的查询,查看执行计划
SQL> select * from test_f where no is null;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 348613680
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_F | 1 | 8 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST_F_A | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("NO" IS NULL)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
394 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
--发现此时应用了该列上的所有,实现了索引范围扫描。
因此可以通过此方法 来解决在可能包含null值 和对该类有可能进行null值查询的列,建立此复合索引来在查询中使用索引提高效率
二:建立nvl函数索引
SQL> drop index test_f_a;
Index dropped.
SQL> create index test_f_a on test_f(nvl(no,0));
Index created.
SQL> exec dbms_stats.gather_table_stats('SYS','TEST_F',CASCADE=>TRUE);
PL/SQL procedure successfully completed.
--在对no列进行与null值查询的时候 使用nvl(no,0)查询。
SQL> select * from test_f where nvl(no,0)=0;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 348613680
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_F | 1 | 12 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST_F_A | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(NVL("NO",0)=0)
Statistics
----------------------------------------------------------
14 recursive calls
0 db block gets
27 consistent gets
0 physical reads
0 redo size
394 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
0 rows processed
--此时也能达到在no列空值查询使用索引的效果
- oracle null值应用索引
- NULL 值与索引
- 索引和NULL值
- NULL 值与索引
- oracle索引应用
- Oracle null列 强制索引经验
- Oracle is null不走索引问题
- NULL 值与索引(一)
- NULL 值与索引(二)
- [Index]Null值和索引
- null值如何使用索引
- NULL 值与索引(一)
- 列值有NULL值创建索引
- ORACLE索引列NULL值引发执行计划该表的测试示例
- oracle null值处理
- Oracle的null值
- Oracle 的 Null 值
- Oracle中null值
- 商业智能简史( A History of Businesss Intelligence)
- .SAXParseException: unterminated entity ref (position:ENTITY_REF
- C语言中的数组
- 让操作javascript对象数组像.net lamda表达式一样
- cocos2dx安装、配置、移植总结
- oracle null值应用索引
- 内存泄漏检测
- 测试wince wifi漫游的方法(参考)
- mysql常用的操作(一)
- 游骑兵的心愿
- DB2 9数据库分布式管理之执行节流的实用程序
- MFC利用CFileFind 类实现文件夹的复制
- udp套接字编程 C#
- unable to resolve target “android_8”