null值如何使用索引
2013-12-31 00:07
155 查看
SQL> create table as select * from all_object; SQL> alter table test modify object_name null; Table altered. SQL> update test set object_name = null where object_id =10000; 1 row updated. SQL> commit; ----------------------创建普通的B*树索引 SQL> create index idx_test_1 on test(object_name); Index created. SQL> exec dbms_stats.gather_table_stats(user,'TEST',cascade=>true); PL/SQL procedure successfully completed. SQL> SELECT * FROM TEST WHERE OBJECT_NAME IS NULL; Execution Plan ---------------------------------------------------------- Plan hash value: 1357081020 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 97 | 308 (1)| 00:00:04 | |* 1 | TABLE ACCESS FULL| TEST | 1 | 97 | 308 (1)| 00:00:04 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OBJECT_NAME" IS NULL) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 1074 consistent gets 0 physical reads 0 redo size 1597 bytes sent via SQL*Net to client 524 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed ------------------------删除idx_test_1,创建复合索引idx_test_2 SQL> drop index idx_test_1; Index dropped. SQL> create index idx_test_2 on test(object_name,1); Index created. SQL> exec dbms_stats.gather_table_stats(user,'TEST',cascade=>true); PL/SQL procedure successfully completed. SQL> SELECT * FROM TEST WHERE OBJECT_NAME IS NULL; Execution Plan ---------------------------------------------------------- Plan hash value: 620435891 ------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 100 | 4 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 100 | 4 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IDX_TEST_2 | 1 | | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("OBJECT_NAME" IS NULL) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 1597 bytes sent via SQL*Net to client 524 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed ---------------------删除idx_test_2,创建函数索引idx_test3 SQL> drop index idx_test_2; Index dropped. SQL> create index idxx_test_3 on test(nvl(object_name,'xxoo')); Index created. SQL> exec dbms_stats.gather_table_stats(user,'TEST',cascade=>true); PL/SQL procedure successfully completed. SQL> select * from test where nvl(object_name,'xxoo')='xxoo';; Execution Plan ---------------------------------------------------------- Plan hash value: 2118693821 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 242 | 4 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 2 | 242 | 4 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IDXX_TEST_3 | 2 | | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access(NVL("OBJECT_NAME",'xxoo')='xxoo') Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 5 consistent gets 0 physical reads 0 redo size 1597 bytes sent via SQL*Net to client 524 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
总结:普通B*树索引不存储null值,所以无法对 is null条件使用普通B*树索引,要使用索引,有两种方法
1:复合索引,
2:函数索引,
从以上两个测试来看,使用复合索引逻辑读为4,函数索引逻辑读为5,且函数nvl可能需要额外的CPU开销,至于为什么函数索引要比复合索引多一个逻辑读,这个暂时不知道,有待研究.
至于复合索引会增加额外的存储空间,对于现在的存储成本,2个字节(常数1)的空间,完全可以接受.
相关文章推荐
- oracle如何让null值使用索引
- 数据仓库中如何使用索引
- Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——1-5
- SQL Server 索引维护(1)——如何获取索引使用情况
- 使用MYSQL如何挑选索引
- 如何理解并正确使用MySql索引
- 如何查找未使用过的索引
- 如何判断使用复合索引还是使用多个单列索引
- 如何使用MySQL索引?
- MYSQL索引问题:索引在查询中如何使用?(转载)
- ABAP--在查询条件只包含部分索引字段时,如何使用索引
- 【Mysql】索引的应用场景以及如何使用
- bitmap 索引和 B-tree 索引在使用中如何选择
- Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——5-5
- SQL Server 索引维护(1)——如何获取索引使用情况
- 如何监控oracle的索引是否使用
- 如何理解并正确使用MySql索引
- 如何理解并正确使用MySql索引
- ABAP--在查询条件只包含部分索引字段时,如何使用索引
- mysql如何确认复合索引有使用到哪些索引字段的测试