关于索引的几个小问题

索引能在值null上执行么?

B*树索引不能在其索引列都为null值上执行,也就是说B*树索引不存储索引列都为null的。

CODE:

DELETE FROM  KT
CREATE UNIQUE INDEX KT_INDEX ON KT(ID,NAME);
INSERT INTO KT VALUES(1,'KA');
INSERT INTO KT VALUES(2,'EVA');
INSERT INTO KT VALUES(NULL,NULL);
INSERT INTO KT VALUES(3,'HI');
INSERT INTO KT VALUES(NULL,NULL);
analyze index KT_INDEX validate structure;
SELECT NAME,LF_ROWS FROM INDEX_STATS;

从这里可以看到,该索引并不认为(null,null)与(null,null)相等,所以尽管建立了唯一索引,还是能够插入。

在聚集函数看来,他们是相等的。比如:

是否该对外键增加索引?

答案是:除几种特殊情况外,都应该为外键增加索引。这几种特殊的情况包括

1.未删除父表中的行。
2.不论是有意还是无意(如通过一个工具),总之未更新父表的惟一/主键值。
3.不论从父表联结到子表,或者更一般地讲,外键列不支持子表的一个重要的访问途径,而
且你在谓词中没有使用这些外键列从子表中选择数据

除此之外,任何对父表的修改,都会引起字表的全表锁定或者全表扫描。

之外,还有几种不会使用索引的情况:

1,我们在使用一个B*树索引,而且谓词中没有使用索引的最前列。如果是这种情况,可以假设有一个
表T,在T(X,Y)上有一个索引。我们要做以下查询:SELECT * FROM T WHERE Y = 5。此时,优化器就不打
算使用T(x,y)上的索引,因为谓词中不涉及X 列。在这种情况下,倘若使用索引,可能就必须查看每一个
索引条目(稍后我们会讨论一种索引跳跃式扫描,这是一种例外情况),而优化器通常更倾向于T 对做一个
全表扫描。但这并不完全排除使用索引。如果查询是SELECT X, Y FROM T WHERE Y = 5,优化器就会注意
到,它不必全面扫描表来得到X 或Y(X 和Y 都在索引中),对索引本身做一个快速的全面扫描会更合适,
因为这个索引一般比底层表小得多。

2,select * from t where f(indexed_column) = value,即列上使用了函数,这种情况下也不会使用建立的B*索引。如果想使用索引,就建立此函数的函数索引。

3,我们已经对一个字符创建了索引。这个列只包含数值数据。如果所用以下语句来查询:select * from t where indexed_column = 5默认的类型转化,其实也是调用了

to_number的函数,故不会使用索引。

4,使用索引的查询效率比进行全表扫描要慢的多,这时候优化器会自动做出判断,放弃索引扫描。最简单的一个例子就是,查询的行数超过一定的阀值。比如在GENDER列上,性别为男,女的比例为70%对30%。如果你使用索引查询,那么会引起大量的I/O转化,每次扫描一个数据行就要经过几个数据块,进行几次I/O转化,肯定带来效率的降低。这时候优化器会自动选择全表扫描,而放弃索引扫描。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值