Oracle复合索引+空值的索引使用问题

昨天在QQ群里讨论一个SQL优化的问题,语句大致如下:

select A,min(B) from table group by A;--A,B都没有not null约束,A列无空值,B列有空值。--存在复合索引IX_TEST(A,B)

于是手动测试,环境采用Oracle自带的scott用户下的emp表。

1.首先查看如下语句的执行计划(此时表只有主键索引):

2.添加IX_TEST(deptno,comm)后查看执行计划:

发现依然是全表扫描。

3.为deptno列添加非空约束后再次查看执行计划:

4.总结:

Btree索引是不存储空值的,这个是所有使用Btree索引的数据库的共同点。

在本例中我们创建了deptno,comm的符合索引。如果deptno没有非空约束,那么说明有的record不会出现在索引中,此时想要找到min(comm)就必须回表才能确定deptno为null的行是否有comm的值。此时优化器认为全表扫描比扫描索引再回表更为合理,因此选择全表扫描。

当我们添加了非空约束后,deptno不可能为空,因此索引的key值数等于表总行数,另一列comm即便为空也不影响min()取值,只需要扫描索引即可得到所需结果,此时优化器选择索引扫描。

而在Mysql中无论复合索引首列是否存在非空约束,都会使用索引,deptno为null的会全部分在一组取min(comm),可能是Mysql的BTREE索引与Oracle的有所不同,使得首列为空都可以无需回表。

最后:Oracle的列能添加非空约束的一定要添加。

原文地址:https://www.cnblogs.com/leohahah/p/8425813.html

时间: 2024-10-09 06:43:16

Oracle复合索引+空值的索引使用问题的相关文章

Oracle中索引的使用 索引性能优化调整

索引是由Oracle维护的可选结构,为数据提供快速的访问.准确地判断在什么地方需要使用索引是困难的,使用索引有利于调节检索速度. 当建立一个索引时,必须指定用于跟踪的表名以及一个或多个表列.一旦建立了索引,在用户表中建立.更改和删除数据库时, Oracle就自动地维护索引.创建索引时,下列准则将帮助用户做出决定:        1) 索引应该在SQL语句的"where"或"and"部分涉及的表列(也称谓词)被建立.假如personnel表的"firstna

查看Oracle的表中有哪些索引

用user_indexes和user_ind_columns系统表查看已经存在的索引 对于系统中已经存在的索引我们可以通过以下的两个系统视图(user_indexes和user_ind_columns)来查看其具体内容,例如是属于那个表,哪个列和,具体有些什么参数等等. user_indexes:     系统视图存放是索引的名称以及该索引是否是唯一索引等信息. user_ind_column:  系统视图存放的是索引名称,对应的表和列等. 查看索引个数和类别: SQL> select * fr

Oracle之表空间、索引、管理权限及角色

Oracle表空间 表空间是数据库的逻辑组成部分,从物理上讲,数据库数据存放在数据文件中 从逻辑上讲,数据库则是存放在表空间中,表空间由一个或多个数据文件组成 数据库的逻辑结构 oracle中逻辑结构包括表空间.段.区和块 说明一下数据库由表空间构成,而表空间又是由段构成,而段又是由区构成,而 区又是由oracle块构成的这样的一种结构,可以提高数据的效率 表空间用于从逻辑上组织数据库的数据.数据库逻辑上是由一个或是多个表空间组成的 通过表空间可以达到以下作用: 1.控制数据库占用的磁盘空间 2

oracle 优化——索引与组合索引

1.索引结构.第一张图是索引的官方图解,右侧是存储方式的图解. 图中很清晰的展示了索引存储的状况. 在leaf 节点中存储了一列,索引所对应项的 :值,rowId,长度,头信息(控制信息) 这样我们就能很清楚.如果通过索引查找数据,而只需要这个索引的值的时候,写上列名,就可以不需要回表. 2.索引在一般的数据量情况下,只有三层.leaf 是目录,branch 是目录的目录.可以做一个测试 1 drop table t1 purge; 2 drop table t2 purge; 3 drop t

Oracle索引总结(七)- Oracle唯一索引、普通索引及约束的关系

Oracle唯一索引.普通索引及约束的关系 在总结索引扫描类型前(不同于前面总结的五大类索引类型,索引类型主要是索引类别的划分,而索引扫描类型是索引在进行索引扫描时的具体方法),需要了解唯一索引.非唯一索引(普通索引)以及约束的关系.这是因为对于索引扫描类型的具体探讨上,需要根据"唯一索引"."非唯一索引(普通索引)"以及"约束",这三个概念的具体情况,进行具体说明,因此优先进行总结. 1.唯一索引与普通索引的概述 对于索引,如b-tree索引,

mysql复合索引、普通索引总结

对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效.下面用几个例子对比查询条件的不同对性能影响. create table test(a int,b int,c int,KEY a(a,b,c)); 优: select * from test where a=10 and

Oracle性能分析7:索引的使用

这一节主要讲述索引的使用,首先介绍怎么在查询中避免使用索引,然后介绍优化器怎么判断是否使用索引,并介绍了强制使用索引的方法,最后介绍了Oracle的并行处理方法. 避免使用索引 虽然你创建了索引,但有些查询你可能需要避免使用这些索引,或者你为了做一些测试,希望看看各种情况下查询的情况,也希望能够避免使用一些索引或者索引扫描方式.Oracle提供了方式来达到这些目地,就是在查询中使用hint信息,具体情况如下. 避免使用某个索引 如果索引的选择性很差,那么也许使用其它索引或者使用全表扫描的效率会更

41.oracle索引,分析索引,索引碎片整理

概述 索引分为B树索引和位图索引.我们主要研究B树索引,B树索引如下图(图片源自网络): 索引是与表相关的一个可选结构,在逻辑上和物理上都独立于表数据,索引能优化查询,不能优化DML,oracle自动维护索引,频繁的DML操作反而会赢钱大量的索引卫华. 如果sql语句仅仅访问被索引的列,那么数据库只需从索引中读取数据,而不会读取表:如果该语句还要访问未被索引的列,那么数据库会使用rowid来查找表中的行,通常,为检索表数据,数据库以交换方式先读取索引块,然后读取对应的表. 索引的目的是减少IO

【Oracle】第三章索引视图序列

第三章索引视图序列 序列是用来生成唯一,连续的整数的数据库对象.序列是用来自动生成主键或唯一键的值. CREATE SEQUENCE  sequence_name START WITH  integer INCREMENT BY  integer MAXVALUE   integer|nomaxvalue MINVALUE    integer|nominvalue CYCLE|NOCYCLE CACHE  integer|nocache; START WITH     指要生成的第一个序列号,