可空列的索引

时间:2012-02-07 11:40:03

标签: sql database performance oracle indexing

我有一个可以为空的列的索引,我想选择它的所有值,如下所示:

SELECT e.ename 
FROM   emp e;

在解释计划中,我看到FULL TABLE SCAN(甚至提示没有帮助)

SELECT e.ename 
FROM   emp e
WHERE  e.ename = 'gdoron';

是否使用索引......

我用google搜索并发现索引中没有空条目,因此第一个查询无法使用索引。

我的问题很简单:为什么索引中没有空条目?

3 个答案:

答案 0 :(得分:17)

默认情况下,关系数据库忽略NULL值(因为关系模型表明NULL表示“不存在”)。因此,Index不存储NULL值,因此如果SQL语句中有空条件,则忽略相关索引(默认情况下)。

但您可以解决此问题,请查看THISTHIS文章。

答案 1 :(得分:3)

如果您从表中获取所有行,为什么您认为它应该使用索引?全表扫描是返回所有值的最有效方法。它与没有在索引中的空值无关,也与优化器选择最有效的检索数据的方法有关。


@ A.B.Cade:优化器可能会选择使用索引,但不太可能。假设您有一个包含100行的索引表的表,但只有10个值。如果优化器使用索引,则必须从索引获取10行,然后将其扩展为100行,而使用全表扫描,它将从get-go获取所有100行。这是一个例子:

create table test1 (blarg varchar2(10));

create index ak_test1 on test1 (blarg);

insert into test1
select floor(level/10) from dual connect by level<=100;

exec dbms_stats.gather_table_stats('testschema','test1');

exec dbms_stats.gather_index_stats('testschema','ak_test1');

EXPLAIN PLAN FOR
select * from test1;

我的观点主要是这个问题主要基于一个有缺陷的前提:索引扫描本质上比全表扫描更好。这种情况并非总是如此。

答案 2 :(得分:0)

我不确定第一个查询在索引使用方面是否相关,至少第二个可以。

无论如何,虽然您无法索引包含空值的列,但有一些方法可以执行此操作,例如:

create index MY_INDEX on emp(ename, 1);

注意结尾处的, 1)