【发布时间】:2012-03-06 19:57:13
【问题描述】:
我正在制作将插入大约的应用程序。 1500万条记录成一张表,然后建一个索引。大约需要。 30分钟创建索引(附索引优化提示,如NOLOGGING)。我可以选择插入按我稍后将构建索引的相同列排序的数据。
这样做会获得任何性能吗?
我是开发人员,而不是 DBA,如果这是一个显而易见的答案,请原谅。
【问题讨论】:
我正在制作将插入大约的应用程序。 1500万条记录成一张表,然后建一个索引。大约需要。 30分钟创建索引(附索引优化提示,如NOLOGGING)。我可以选择插入按我稍后将构建索引的相同列排序的数据。
这样做会获得任何性能吗?
我是开发人员,而不是 DBA,如果这是一个显而易见的答案,请原谅。
【问题讨论】:
如果您已经对数据进行了排序,那么在创建索引时,您可以使用 NOSORT 关键字告诉 Oracle 它不需要再次对数据进行排序。
CREATE INDEX index_name ON table_name (col1, col2) NOSORT;
排序 | NOSORT 默认情况下,Oracle 数据库按升序对索引进行排序 创建索引时的顺序。您可以指定 NOSORT 以指示 行已存储在数据库中的数据库 升序,这样 Oracle 数据库就不必对 创建索引时的行。如果索引列的行或 列不按升序存储,则数据库返回 一个错误。为了最大程度地节省排序时间和空间,请使用此子句 在将行初始加载到表中之后立即。如果你 不指定这两个关键字,那么 SORT 是默认值。
【讨论】:
我也不是 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 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 子句中进行任何更改后,排序的数据都会更快。
【讨论】:
这样做您可能不会获得任何整体性能。
排序表数据所花费的时间将超过构建索引所获得的时间。 (尽管如果您要构建多个索引,情况可能会有所不同。)
对表进行排序需要与整个表大小一样多的内存或临时表空间。我不确定索引构建的内部结构,但我猜 Oracle 只会对(小得多的)相关数据进行排序。
由于您使用多个列,因此您可能需要研究索引压缩。根据您的数据和列顺序,它可以在初始构建时为您节省大量时间和空间。
【讨论】: