Oracle更改索引以允许对空值进行索引

时间:2016-10-07 05:26:17

标签: sql oracle indexing

不幸的是,一个巨大的表中的一列具有一半数据的空值,因此在查询时

select count(*) from huge_table where half_null_col is null;
即使已经编入索引,

也将是一场性能灾难:

create index half_null_col_idx on huge_table(half_null_col asc);

有两个问题:

  1. Oracle 11g应该support a constant expression to index on null values,但很抱歉我通过了oracle doc但是找不到关于它的明确的官方文档。如果有人知道,请分享参考资料

  2. 如何再次更改索引而不是dropcreate以避免性能问题。

1 个答案:

答案 0 :(得分:7)

目前我至少有四种选择:

  1. 创建"常量表达式"指数...

    create index half_null_col_idx
    on huge_table (half_null_col, 1);
    
  2. 在表格上创建位图索引。位图索引也允许索引NULL ...

    create bitmap index half_null_col_idx
    on huge_table (half_null_col);
    
  3. 在基于函数的NULL重新映射到某个值上创建索引,并在查询中使用重新映射的NULL,而不是查询NULL ...

    create index half_null_col_idx
    on huge_table (nvl(half_null_col, '<a value that does not appear in the values of the column>'));
    
    select *
    from huge_table
    where nvl(half_null_col, '<a value that does not appear in the values of the column>')
        = '<a value that does not appear in the values of the column>'
    ;
    
  4. 重新分区表,以便将NULL值全部放入一个分区,将其余值放入不同的分区/分区......

    create table huge_table_2
    partition by list (half_null_col)
    (
        partition pt_nulls values (null),
        partition pt_others values (default)
    )
    as
    select *
    from huge_table;
    
  5. 如果您只从表中选择count(*),那么位图索引可能是您的最佳选择。

    如果您想在其他地方使用表中的完整数据行(在连接到另一个表或将它们导出到CSV或其他表格),那么重新分区可能是您的最佳选择。

    如果您不能重新对表格进行重新分区而无法创建位图索引(例如,由于桌面上的并发DML活动较多),那么&# 34;不断表达&#34; index或&#34; NULL-remapped-to-something&#34;索引可能是你最好的选择。

    回答您的原始问题:

    1. Oracle内部将它们作为&#34;基于函数的索引&#34;。或许可以搜索这个词。
    2. 你不能。但是,在线索引下降+创建afaik没有相关的性能开销。 Oracle DB非常适合处理&#34;多任务处理&#34;这里的东西 - 创建你的索引以及你的应用程序几乎像以前一样快速工作。如果您需要重新创建索引,请执行此操作。如果你选择&#34;常数表达&#34;选项,您可以先创建新索引,然后删除旧索引。