创建索引组织表的问题

Tim*_*our 3 oracle

我对索引组织表有一个奇怪的问题.我正在运行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
Run Code Online (Sandbox Code Playgroud)

现在让我们创建另一个表并从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
Run Code Online (Sandbox Code Playgroud)

甲骨文花了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; 
Run Code Online (Sandbox Code Playgroud)

"插入"IOT需要18个小时!我已经在win和linux上运行的2个不同的Oracle实例上尝试过,并得到了相同的结果.

这里发生了什么 ?为什么需要这么长时间?

Dav*_*sta 8

APPEND提示仅对堆组织表有用.

当您插入IOT时,我怀疑每行必须分别插入到真实的索引结构中,从而导致索引的大量重新平衡.

在堆表上构建索引时,会使用临时段,我猜这可以减少重新平衡的开销.

我怀疑如果你用主键创建一个空的,堆组织的表,并且在没有APPEND提示的情况下执行相同的插入,则需要18个小时.

您可以尝试在SELECT上放置ORDER BY,看看它如何影响IOT插入的性能.它无法保证通过任何方式得到改善,但它可能是.