2012-03-06 80 views
2

我正在制作应用程序,将1500万条记录放入表格中,然后建立一个索引。它大约需要。 30分钟创建索引(使用索引优化提示,例如NOLOGGING)。我可以选择插入按相同列排序的数据,我将在后面构建索引。从订购数据构建Oracle索引

我会这样做吗?

我是开发人员,而不是DBA,所以请原谅,如果这是一个明显的答案。

回答

6

如果您已经对数据进行了排序,那么当您创建索引时,可以告诉Oracle它不需要使用NOSORT关键字对数据重新排序。

CREATE INDEX index_name ON table_name (col1, col2) NOSORT; 

SORT | NOSORT默认情况下,Oracle数据库在创建索引时按升序排列索引 。您可以指定NOSORT向 数据库指示行已按 升序排列存储在数据库中,以便Oracle数据库在创建索引时不必对 行进行排序。如果索引列或 列的行未按升序存储,那么数据库将返回 错误。为了最大限度地节省排序时间和空间,请在将行初始加载到表中后立即使用本条款 。如果你 既不指定这些关键字,那么SORT就是默认值。

1

我也不是DBA,但我很好奇并且做了测试(如果有人认为我的测试无效,请让我知道)。

我创建表

CREATE TABLE TEMP (
    ID_TEMP NUMBER(10) NOT NULL, 
    SOME_DATE DATE NOT NULL, 
    SOME_TEXT VARCHAR2(60) NOT NULL, 

    CONSTRAINT TEMP_PK primary key (ID_TEMP) 

); 

然后填充具有随机值

declare 
    vdate date; 
begin 
    for idx in 0..10000000 loop 
    vdate := sysdate - dbms_random.value(0,102548); 
    insert into temp values(idx, vdate, 'something'); 
    end loop; 
    commit; 
end; 

之后,该指数:

create index TEMP_DATE_NDX ON TEMP (SOME_DATE) NOLOGGING; 
-- index TEMP_DATE_NDX created. Elapsed: 00:00:24.650 

然后我DROP掉该表并重新创建,但这次我按顺序插入记录:

DROP TABLE TEMP; 
-- create table omitted... 
declare 
    vdate date; 
begin 
    for idx in 0..10000000 loop 
    vdate := trunc(sysdate) + idx; 
    insert into temp values(idx, vdate, 'something'); 
    end loop; 
    commit; 
end; 

create index TEMP_DATE_NDX ON TEMP (SOME_DATE) NOLOGGING; 
-- index TEMP_DATE_NDX created. Elapsed: 00:00:01.993 

正如您所看到的,随着create index子句的任何更改,有序数据更快。

0

这样做可能不会获得任何整体表现。

您将失去更多时间对表格数据进行排序,而不是您从构建索引获得的时间。 (虽然如果您构建多个索引,情况可能会有所不同)。

排序表需要与整个表的大小一样多的内存或临时表空间。我不确定索引构建的内部结构,但我猜测Oracle只会对(小得多的)相关数据进行排序。

由于您正在使用多列,因此您可能需要查看索引压缩。根据您的数据和列顺序,它可以为您在初始构建中节省大量时间和空间。

+0

我不在oracle中排序数据。我的问题是,如果我通过以已排序的顺序输入记录而获益。指数的构建会更快吗? – Jeffrey 2012-03-07 14:27:00

+0

但是,有些系统不需要为这种排序付出代价吗?如果没有,那么你也可以对它进行分类。对表格数据排序也会降低聚类因子,这可能会使索引更有效地使用。如果您使用表格数据,排序表格数据也可以帮助您进行表格压缩。 – 2012-03-08 00:04:46