暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle SQL 语句没有过滤条件,究竟是否会走索引??

kk的DBA随笔 2024-10-23
16

答案是:可能走索引也可能不走索引,具体要看列的值可不可为 null,Oracle 不会为所有列的 nullable 属性都为 Y 的 sql 语句走索引。

例子:

  1. create table t as select * from dba_objects;

复制
  1. CREATE INDEX ix_t_name ON t(object_id, object_name, owner);

复制
  1. SELECT object_id, object_name, owner FROM t;

复制

看到网上很多的文章都会说第三个 SQL 语句没有 where 条件,肯定不走索引,或者 说 这个语句的列上都有索引,会走覆盖索引,真的是这样吗?

第三个 DQL 语句会走索引吗? -- 不会。因为虽然查询的这三个列都被覆盖索引包含在内,但这三个列都可为 null,正如开篇所说——Oracle 不会为全都为 null 的行走索引。执行计划如下:

可以看到这三个列虽然都有索引,但这三个列的 nullable 属性都是 Y,也就是都可为空,所以索引将失效,该语句将走全表扫描。

解决这个问题,至少将其中一列的 nullable 属性设置为 N。这样就保证了每一行都将在索引中。

  1. alter table t

  2. modify object_name not null;

复制

再次查询同样的 SQL 语句,可以看到没有 where 条件的 SQL 语句也走了索引。

所以,一个 sql 语句没有 where 条件会不会走索引是一个有争议的问题。所以碰到这种问题只需要记得

Oracle 不会为所有列的 nullable 属性都为 Y 的 SQL 语句走索引。

所以,我们也可以换一种方式解决,为 object_id 添加主键约束? 设置其它两列为 notnull? 都是解决问题的方案。


文章转载自kk的DBA随笔,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论