我对索引组织表有一个奇怪的问题。我正在运行Oracle 11g标准。
我有一张表src_table
SQL> desc src_table;
Name Null? Type
--------------- -------- ----------------------------
ID NOT NULL NUMBER(16)
HASH NOT NULL NUMBER(3)
........
SQL> select count(*) from src_table;
COUNT(*)
----------
21108244
现在让我们创建另一个表并从src_table
复制2列set timing on
SQL> create table dest_table(id number(16), hash number(20), type number(1));
Table created.
Elapsed: 00:00:00.01
SQL> insert /*+ APPEND */ into dest_table (id,hash,type) select id, hash, 1 from src_table;
21108244 rows created.
Elapsed: 00:00:15.25
SQL> ALTER TABLE dest_table ADD ( CONSTRAINT dest_table_pk PRIMARY KEY (HASH, id, TYPE));
Table altered.
Elapsed: 00:01:17.35
Oracle< 2分钟。
现在同样的练习,但有IOT表
SQL> CREATE TABLE dest_table_iot (
id NUMBER(16) NOT NULL,
hash NUMBER(20) NOT NULL,
type NUMBER(1) NOT NULL,
CONSTRAINT dest_table_iot_PK PRIMARY KEY (HASH, id, TYPE)
) ORGANIZATION INDEX;
Table created.
Elapsed: 00:00:00.03
SQL> INSERT /*+ APPEND */ INTO dest_table_iot (HASH,id,TYPE)
SELECT HASH, id, 1
FROM src_table;
“插入”IOT需要 18小时 !!!我已经在win和linux上运行的2个不同的Oracle实例上尝试了它,并得到了相同的结果。
这里发生了什么?为什么需要这么长时间?
答案 0 :(得分:8)
APPEND提示仅对堆组织表有用。
当您插入IOT时,我怀疑每行必须分别插入到真实的索引结构中,从而导致索引的大量重新平衡。
在堆表上构建索引时,会使用临时段,我猜这可以减少重新平衡的开销。
我怀疑如果您使用主键创建了一个空的,堆组织的表,并且在没有APPEND提示的情况下执行相同的插入,则需要更多的时间来执行18小时。
您可以尝试在SELECT上放置ORDER BY,看看它如何影响IOT插入的性能。无论如何都不能保证它是一种改进,但它可能是。