我有一个可以为空的列的索引,我想选择它的所有值,如下所示:
SELECT e.ename
FROM emp e;
在解释计划中,我看到FULL TABLE SCAN
(甚至提示没有帮助)
SELECT e.ename
FROM emp e
WHERE e.ename = 'gdoron';
是否使用索引......
我用google搜索并发现索引中没有空条目,因此第一个查询无法使用索引。
我的问题很简单:为什么索引中没有空条目?
答案 0 :(得分:17)
默认情况下,关系数据库忽略NULL值(因为关系模型表明NULL表示“不存在”)。因此,Index不存储NULL值,因此如果SQL语句中有空条件,则忽略相关索引(默认情况下)。
答案 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)
。