仅为Oracle 10g中的查询创建索引

时间:2010-01-05 04:18:24

标签: oracle indexing oracle10g

我在Oracle 10g的特定表中有大约350万条记录,我想查询一个特定列具有NULL值的所有记录。

我的问题是,为了那个查询的目的,是否值得在该列上创建索引?使用索引节省的时间是否会补偿创建它所需的时间?或者我应该在没有索引的情况下进行查询?

请注意,我没有提前为我创建索引的选项,如果我只为查询创建索引,我必须立即删除它。

p / s:我确实搜索了现有的问题,但找不到我想要的答案。请指出我可能错过的任何类似问题。

4 个答案:

答案 0 :(得分:4)

创建索引将比单个查询昂贵得多。如果没有索引,查询将只需要扫描表。构建索引还必须扫描表 - 然后构建并编写索引。

答案 1 :(得分:2)

如果我没记错,Oracle不会为NULL值编制索引;因此,如果进入索引的所有字段都为NULL,则该行没有索引条目。例如,如果您有一个类似

的表格
ID      NUMBER PRIMARY KEY
FIELD1  NUMBER
FIELD2  NUMBER

带索引

ID_INDEX (ID) PRIMARY KEY
FIELD1_INDEX (FIELD1)
FIELD2_INDEX (FIELD2)

和数据

ID=1  FIELD1=NULL  FIELD2=1
ID=2  FIELD1=2     FIELD2=NULL
ID=3  FIELD1=3     FIELD2=3
ID=4  FIELD1=NULL  FIELD2=NULL

ID_INDEX中应该有四个条目,但FIELD1_INDEX和FIELD2_INDEX中只有两个条目。您可以通过查询DBA_IND_STATISTICS视图(收集表统计信息后)来验证这一点:

SELECT * FROM DBA_IND_STATISTICS WHERE TABLE_NAME = 'whatever';

并查看DISTINCT KEYS和NUM_ROWS列。

所有这一切的结果是,如果您有一个查询在特定列中查找NULL值,那么很可能您最终会进行全表扫描。我相信聚簇索引实际上可以索引NULL值条目,但我没有使用它们所以我不确定。

我希望这会有所帮助。

答案 2 :(得分:1)

您能否以NULL值在单个分区中结束的方式对表进行分区?如果我没有弄错(抱歉,现在无法测试),NULL值将转到范围分区表中的MAXVALUE分区。我认为Oracle会很好地进行分区消除,因此只扫描包含NULL值的分区。您只需选择一个合适的数字作为前一个分区的高值,以便消除大部分或全部不需要的行。

示例(比如my_column是一个数字,你想找到NULL):

create table test_table (
  my_column number,
  other_columns ...
)
partition by range (my_column)
(
  partition not_null values less than (99999999999999),
  partition nulls    values less than (MAXVALUE)
);

然后,如果你“从my_column为空的test_table中选择*”执行计划应该只显示正在扫描的分区“空值”(完全扫描,但它主要只包含你想要的内容)。

如果值可以从null更新为非null,请记住启用行移动,反之亦然。

答案 3 :(得分:1)

如果你有Enterprise Edition并且你有一个多CPU系统,那么你应该考虑使用并行查询。这是从全表扫描中获取结果的最快方法,尽管它确实具有管理开销,并且确实需要多个CPU的可用性(显然),