我在一个可空列上创建了索引,并希望像这样选择它的所有值:
SELECT e.ename
FROM emp e;
在执行计划中,我看到了一个 FULL TABLE SCAN
(即使使用提示也没有帮助)
SELECT e.ename
FROM emp e
WHERE e.ename = 'gdoron';
我在谷歌上查到索引中没有空条目,因此第一个查询无法使用索引。
我的问题很简单:为什么索引中没有空条目?
我在一个可空列上创建了索引,并希望像这样选择它的所有值:
SELECT e.ename
FROM emp e;
在执行计划中,我看到了一个 FULL TABLE SCAN
(即使使用提示也没有帮助)
SELECT e.ename
FROM emp e
WHERE e.ename = 'gdoron';
我在谷歌上查到索引中没有空条目,因此第一个查询无法使用索引。
我的问题很简单:为什么索引中没有空条目?
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;
我的观点是,这个问题很大程度上基于一个错误的前提:索引扫描本质上比全表扫描更好。但事实并非总是如此,正如这个场景所展示的。
我不确定第一个查询在索引使用方面是否相关,至少第二个查询是可以的。
无论如何,虽然不能对包含空值的列进行索引,但有一些方法可以实现,例如:
create index MY_INDEX on emp(ename, 1);
, 1)
,这是关键所在。create index MY_INDEX on emp(NVL(ename, 'null'));
吗? - gdoron
hint
再次尝试,但没有帮助的原因... - gdoronwhere e.ename is not null
即可完成。当然,如果您选择了任何无法仅通过索引提供服务的列,则最终将得到一个全文搜索(除非您强制使用提示,在这种情况下,它将使用您的索引,但实际上会导致更差的IO性能)。 - rejjename
上,这也是意味着的话,优化器完全可以选择全索引扫描而不是全表扫描,但如果有空值的话就不行了。 - Dave Costa