Oracle:使用索引来搜索空值

时间:2012-01-27 16:27:52

标签: oracle

3 个答案:

答案 0 :(得分:2)

使用NVL2的功能索引怎么样,比如;

CREATE TABLE foo (bar INTEGER);
INSERT INTO foo VALUES (1);
INSERT INTO foo VALUES (NULL);
CREATE INDEX baz ON foo (NVL2(bar,0,1));

然后;

DELETE plan_table;
EXPLAIN PLAN FOR SELECT * FROM foo WHERE NVL2(bar,0,1) = 1;
SELECT operation, object_name FROM plan_table;

应该给你

OPERATION        OBJECT_NAME
---------------- -----------
SELECT STATEMENT
TABLE ACCESS     FOO
INDEX            BAZ        << yep

答案 1 :(得分:1)

我将“回答”上面的非问题。

您链接的文章是正确的 - 当叶节点为空时,Oracle的b树索引将无法捕获。举个例子:

CREATE TABLE MYTABLE (
  ID  NUMBER(8) NOT NULL,
  DAT VARCHAR2(100) 
);

CREATE INDEX MYTABLE_IDX_1 ON MYTABLE (DAT);

/* Perform inserts into MYTABLE where some DAT are null */

SELECT COUNT(*) FROM MYTABLE WHERE DAT IS NULL;

结尾SELECT将无法使用索引,因为叶子(最右边的列)不会捕获空值。 Burleson的解决方案很愚蠢,因为现在您必须在所有查询中使用NVL并且已经破坏了表中的数据。戈尔巴乔夫的方法包括一个用于b树叶子的已知NOT NULL列,但这无缘无故地扩展了索引。也许在他的情况下,索引对于调整其他查询是有意义的,但如果您想要做的就是找到NULL s,那么最简单的解决方案是使叶子保持不变。

CREATE INDEX MYTABLE_IDX_1 ON MYTABLE (DAT, 1);

现在,叶子都是常量(1),默认情况下,空值将全部在一起(在索引的顶部或底部,但它并不重要,因为Oracle可以使用索引转发或向后)。该常量存在轻微的存储损失,但是单个数字小于典型表中的大多数其他数据字段。现在,数据库可以在查询空值时使用索引...如果优化器发现获取数据的最佳方法。

答案 2 :(得分:1)

如果您问,“如何创建一个允许在特定字段上搜索NULL值时使用的索引”,我的建议是在您对PLUS感兴趣的字段上创建索引主键字段。因此,如果你有一个名为A_TABLE的表,你想要搜索NULL的字段VAL和一个名为PK的主键,我会在(VAL,PK)上创建一个索引。

分享并享受。