Oracle Null系列(三)

null 和执行计划

总结:至少要保证查询的记录要建立索引,才能使用索引

1.单列唯一索引

  1. 由于null值是不被建立索引,所以当使用id is null作为谓词时,走了全表扫描。
    null索引链接: null 和索引
    在这里插入图片描述

  2. 因为id列不为空的记录都建立了索引。所以当使用 id is not null 作为谓词时,此时执行计划中走了索引全扫描(当数据量较大时,就会全表扫描,因为通过索引获取可能性能更低)。
    在这里插入图片描述

2.复合唯一索引

  1. 对于复合唯一索引的情形,当使用单列谓词时,使用 is null 与 is not null 等同于单列唯一索引的情形, is null走全表扫描而 is not null走索引。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  2. 对于复合唯一索引的情形,当使用所以索引列谓词时,同时不为空(and)走索引,其他情况都不走索引。

  • id is null and name is null
    在这里插入图片描述

  • id is null or name is null
    在这里插入图片描述

  • id is not null and name is not null
    在这里插入图片描述

  • id is not null or name is not null
    在这里插入图片描述

3.is null 走索引

3.1 添加 not null 约束

  1. 索引列添加 not null 约束,单列索引任然不走索引
    在这里插入图片描述

按理来说(索引列有not null 约束,此列肯定没有null值),不应该走全部扫描,直接返回空(但人家没按照我的道理走

  1. 组合索引中,第一个字段没有出现在where语句中,此时走复合索引(id列有not null 约束,保证了复合索引给表的所有行建立了索引)
    在这里插入图片描述

3.2 通过函数索引来使得is null使用索引

create unique index ipk_study$f_id on study(nvl(id,-1));

3.3 使用伪列创建基于函数的索引来使得is null使用索引

create unique index ipk_study$r_id on study(id,-1);

3.4 总结

    无论是单列唯一索引或复合唯一索引,对于可以为null的列或复合null值,Oracle不会为其存储索引值。故在基于单列创建B树唯一索引或多列创建B树复合唯一索引的情形下,
当列上允许为null值时:

  • where子句使用了基于is null的情形,其执行计划走全表扫描。
  • where子句使用了基于is not null的情形,其执行计划走索引扫描。

当列上不允许为null值时,存在非null约束:

  • where子句使用了基于is null的情行,其执行计划走索引扫描。
  • where子句使用了基于is not null的情形,其执行计划走索引扫描。

Null与索引使用时的建议:

  1. 对于用于连接或经常被谓词使用到的列应尽可能避免NULL值属性,因为它容易导致索引失效。
  2. 为需要使用NULL值的列添加缺省值(alter table tb modify(col default ‘Y’))。
  3. 如果NULL值不可避免也不能使用缺省值,应考虑为该常用列使用nvl函数创建索引,或使用伪列来创建索引以提高查询性能。
  4. 对于复合索引应保证索引中至少有一列不为NULL值,还是因为全部列为NULL时不被索引存储,以保证使用is null是可以使用索引。
  5. 对于复合索引应保证索引列应使用数据类型长度最小的列来添加not null约束应节省磁盘空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ts16dmy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值