HINT无效的几个场景

碰巧看见了dba-oracle上的一个问题,算是基础性问题,
问题就是某些检索中,即使指定了INDEX HINT,可能无效。
回答是,如果这个INDEX HINT的语法格式错误,就会只将他看作一个注释,不会应用这个HINT。

IN
INDEX HINT的标准用法是/*+ index(table_name, index_name) */,其中的","可以省略,换成空格。

举出了几个正确的使用,测试表和数据,
SQL> select * from customer;
ID A


 1 a
 2 b
 3 c
 4 d
 5 e

一开始,只是为这个id创建了索引,

SQL> create index pk_customer on customer(id);
Index created.

此时执行INDEX HINT的SQL,

SQL> select /*+ index(customer, pk_customer) */ * from customer;

发现这个HINT未生效,语法格式没问题,这是什么错?

这个隐藏的问题,其实就是索引的内容,因为索引不包含空值,换句话说,id列可能为空,因此索引中就可能为空,CBO认为HINT会导致错误结果,那么这个HINT就会被忽略,所以选择了全表扫描。

解决方案就是设置这个id非空约束,为了测试,直接将其设置为主键,这藏着另一个知识点,之前在摩天轮中看见个问题,如何创建主键,这两种操作,都是正确的,区别就是第一种可以设置主键约束的名称,第二种会由系统自动创建一个名称,例如SYS_C000000,从标准的角度看,建议第一种,

SQL> alter table customer add constraint pk_customer primary key(id);
Table altered.

SQL> alter table customer add primary key (id);
Table altered.

回到主题上,此时执行INDEX HINT的SQL,

SQL> select /*+ index(customer, pk_customer) */ * from customer;

此时使用了索引全扫描,说明这个HINT生效了,

如果检索的表设置了别名,INDEX HINT就需要使用别名,不能是这个表名,

  1. 使用表名,

SQL> select /*+ index(customer, pk_customer) */ * from customer c;
INDEX HINT无效,

  1. 使用别名,
    SQL> select /*+ index(c, pk_customer) */ * from customer c;
    INDEX HINT生效,

如果多个HINT冲突了,HINT无效,
SQL> select /*+ full(customer) index(customer pk_customer) */ * from customer;
显示未用索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值