sql tuning--列是否为空is not null与索引index是否可用的关系

附件

前言

    sql是否可以使用索引,与很多因素有关,比如WHERE条件列的选择度,表及列的统计信息,可能还包括列是否为空,本文仅讨论索引是否为空,与索引是否使用的一些关系

测试结论

    
    1,对于select 索引列 from 表名,如果索引列为is null,仍不会使用索引
       即使强制使用index hint,也无法使用索引扫描
    2,原因在于索引的结构为B树索引,而B树索引里面不包括列为NULL值的数据信息,如果强制使用索引,会把NULL值对应的记录遗漏掉
    3,所以如果想在第1涉及的SQL使用索引,索引列必须定义时为IS NOT NULL或者在
       SQL WHERE条件列 IS NOT NULL

测试明细

   

SQL> create table t_null_nonnull(a int,b int);
Table created.
SQL> create table t_null_nonnull(a int,b int);
Table created.
SQL> desc t_null_nonnull;
Name Null? Type
----------------------------------------- -------- ----------------------------
A NUMBER(38)
B NUMBER(38)
SQL> insert into t_null_nonnull select level,level from dual connect by level<=10000;
10000 rows created.
SQL> commit;
Commit complete.
SQL> select a from t_null_nonnull;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1444422154
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T_NULL_NONNULL | 10000 | 126K| 7 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
689 consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>
SQL> create index idx_t_nonnull on t_null_nonnull(a);
Index created.
SQL> select a from t_null_nonnull;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1444422154
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T_NULL_NONNULL | 10000 | 126K| 7 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
5 recursive calls
0 db block gets
689  consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>
SQL> select /*+ index(t_null_nonnull idx_t_nonnull) */ a from t_null_nonnull;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1444422154
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T_NULL_NONNULL | 10000 | 126K| 7 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
689 consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>

SQL> alter table t_null_nonnull modify a not null;
Table altered.
SQL> set linesize 30
SQL> desc t_null_nonnull;
Name Null? Type
----------------- -------- ------------
A NOT NULL NUMBER(38)
B NUMBER(38)
SQL> select a from t_null_nonnull;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1444422154
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T_NULL_NONNULL | 10000 | 126K| 7 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
689 consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>
SQL> select /*+ index(t_null_nonnull idx_t_nonnull) */ a from t_null_nonnull;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 4141558108
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 27 (0)| 00:00:01 |
| 1 | INDEX FULL SCAN | IDX_T_NONNULL | 10000 | 126K| 27 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
687 consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>
SQL> set autot off
SQL> truncate table t_null_nonnull;
Table truncated.
SQL> insert into t_null_nonnull select level,level from dual connect by level<=10000;
10000 rows created.
SQL> commit;
Commit complete.
SQL> select a from t_null_nonnull;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 315757037
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
| 1 | INDEX FAST FULL SCAN| IDX_T_NONNULL | 10000 | 126K| 7 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
4 recursive calls
0 db block gets
715 consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>
SQL> alter table t_null_nonnull modify a null;
Table altered.
SQL> select a from t_null_nonnull;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1444422154
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T_NULL_NONNULL | 10000 | 126K| 7 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
187 recursive calls
0 db block gets
739 consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>
SQL> select a from t_null_nonnull where a is not null;
10000 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 315757037
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10000 | 126K| 7 (0)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| IDX_T_NONNULL | 10000 | 126K| 7 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A" IS NOT NULL)
Note
-----
- dynamic sampling used for this statement (level=2)

Statistics
----------------------------------------------------------
5 recursive calls
0 db block gets
715 consistent gets
0 physical reads
0 redo size
174298 bytes sent via SQL*Net to client
7845 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10000 rows processed
SQL>

个人简介

8年oracle从业经验,具备丰富的oracle技能,目前在国内北京某专业oracle服务公司从事高级技术顾问。
   
   服务过的客户:
          中国电信
          中国移动
          中国联通
          中国电通
          国家电网
          四川达州商业银行
          湖南老百姓大药房
          山西省公安厅
          中国邮政
          北京302医院     
          河北廊坊新奥集团公司
  
 项目经验:
           中国电信3G项目AAA系统数据库部署及优化
           中国联通CRM数据库性能优化
           中国移动10086电商平台数据库部署及优化
           湖南老百姓大药房ERR数据库sql优化项目
           四川达州商业银行TCBS核心业务系统数据库模型设计和RAC部署及优化
           四川达州商业银行TCBS核心业务系统后端批处理存储过程功能模块编写及优化
           北京高铁信号监控系统RAC数据库部署及优化
           河南宇通客车数据库性能优化
           中国电信电商平台核心采购模块表模型设计及优化
           中国邮政储蓄系统数据库性能优化及sql优化
           北京302医院数据库迁移实施
           河北廊坊新奥data guard部署及优化
           山西公安厅身份证审计数据库系统故障评估
           国家电网上海灾备项目4 node rac+adg 
          贵州移动crm及客服数据库性能优化项目
          贵州移动crm及客服务数据库sql审核项目
          深圳穆迪软件有限公司数据库性能优化项目
 联系方式:
          手机:18201115468
          qq   :   305076427
          qq微博: wisdomone1
          新浪微博:wisdomone9
          qq群:275813900    
          itpub博客名称:wisdomone1     http://blog.itpub.net/9240380/

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

转载于:http://blog.itpub.net/9240380/viewspace-1694512/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值