索引能在值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转化,肯定带来效率的降低。这时候优化器会自动选择全表扫描,而放弃索引扫描。