You Asked
hi tom,
i have to convert a heap table with about 200 million lines into an iot.
my idea is to use direct path inserts to get this job quickly done.
(this approach is very efficient with heap organized tables.)
so i set up a small testcase with heap tables and iots:
(database: oracle 9.2.0.4 on sun solaris)
-- LOGGING
drop table tab_heap1;
create table tab_heap1 (
username varchar2(30) not null,
type varchar2(12) not null,
name varchar2(30) not null,
version number(13) not null,
line number(12) not null,
date_changed date not null
) logging;
set autotrace on
insert into tab_heap1
select owner,type,name,1,line,sysdate from dba_source where rownum < 100000;
timing: 00:00:05.08
statistics
----------------------------------------------------------
511 recursive calls
3846 db block gets
5267 consistent gets
48 physical reads
5456380 redo size
437 bytes sent via SQL*Net to client
619 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
99999 rows processed
-- NOLOGGING
drop table tab_heap2;
create table tab_heap2 (
username varchar2(30) not null,
type varchar2(12) not null,
name varchar2(30) not null,
version number(13) not null,
line number(12) not null,
date_changed date not null
) nologging;
set autotrace on
insert /*+ append */ into tab_heap2
select owner,type,name,1,line,sysdate from dba_source where rownum < 100000;
timing: 00:00:05.03
statistics
----------------------------------------------------------
530 recursive calls
248 db block gets
4613 consistent gets
48 physical reads
27580 redo size
422 bytes sent via SQL*Net to client
633 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
99999 rows processed
--
-- IOT-testcase
--
-- IOT LOGGING
drop table tab_iot1;
create table tab_iot1 (
username varchar2(30) not null,
type varchar2(12) not null,
name varchar2(30) not null,
version number(13) not null,
line number(12) not null,
date_changed date not null,
CONSTRAINT TIOT1_PK PRIMARY KEY (username, type, name, version, line)
)
ORGANIZATION INDEX COMPRESS 3 PCTFREE 0 LOGGING PCTTHRESHOLD 5;
set autotrace on
insert into tab_iot1
select owner,type,name,1,line,sysdate from dba_source where rownum < 100000;
timing: 00:00:21.00
statistics
----------------------------------------------------------
471 recursive calls
18123 db block gets
6012 consistent gets
48 physical reads
18370152 redo size
456 bytes sent via SQL*Net to client
618 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
99999 rows processed
-- IOT NOLOGGING
drop table tab_iot2;
create table tab_iot2 (
username varchar2(30) not null,
type varchar2(12) not null,
name varchar2(30) not null,
version number(13) not null,
line number(12) not null,
date_changed date not null,
CONSTRAINT TIOT2_PK PRIMARY KEY (username, type, name, version, line)
)
ORGANIZATION INDEX COMPRESS 3 PCTFREE 0 NOLOGGING PCTTHRESHOLD 5;
set autotrace on
insert /*+ append */ into tab_iot2
select owner,type,name,1,line,sysdate from dba_source where rownum < 100000;
timing: 00:00:19.05
Statistiken
----------------------------------------------------------
407 recursive calls
18015 db block gets
5978 consistent gets
48 physical reads
18453524 redo size
464 bytes sent via SQL*Net to client
632 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
99999 rows processed
my testcases show that nologging and direct path inserts work fine for heap tables.
it seems that nologging and /*+ append */ do not speed up inserts into index organized tables (same amount of redo)?
are my testcases correct or do i have a fatal mistake in my iot-testcase?
if my testcase is correct, can you explain why inserts into iot's do not benefit from nologging and the append hint?
Thanks!
and Tom said...
append writes above the HWM of a heap table. data in a heap can go "anywhere"
through an index on that heap table and see what happens..
an IOT is a complex data structure, data has a PLACE that is needs to go. you cannot just write "above the HWM".
but...
ops$tkyte@ORA9IR2> select a.name, b.value
2 from v$statname a, v$mystat b
3 where a.statistic# = b.statistic#
4 and lower(a.name) like '%' || lower('&S')||'%'
5 /
old 4: and lower(a.name) like '%' || lower('&S')||'%'
new 4: and lower(a.name) like '%' || lower('redo size')||'%'
NAME VALUE
------------------------------ ----------
redo size 588
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> create table tab_iot2 (
2 username not null,
3 type not null,
4 name not null,
5 version not null,
6 line not null,
7 date_changed not null,
8 CONSTRAINT TIOT2_PK PRIMARY KEY (username, type, name, version, line)
9 )
10 ORGANIZATION INDEX COMPRESS 3 PCTFREE 0 NOLOGGING PCTTHRESHOLD 5
11 as
12 select owner,type,name,1,line,sysdate from dba_source where rownum < 100000;
Table created.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> @mystat2
ops$tkyte@ORA9IR2> select a.name, b.value V, b.value-&V diff
2 from v$statname a, v$mystat b
3 where a.statistic# = b.statistic#
4 and lower(a.name) like '%' || lower('&S')||'%'
5 /
old 1: select a.name, b.value V, b.value-&V diff
new 1: select a.name, b.value V, b.value- 588 diff
old 4: and lower(a.name) like '%' || lower('&S')||'%'
new 4: and lower(a.name) like '%' || lower('redo size')||'%'
NAME V DIFF
------------------------------ ---------- ----------
redo size 112672 112084
use CTAS to do the initial build and you won't have the index merge at the end which is what is causing the redo to be generated.
Rating
(4 ratings)
Is this answer out of date? If it is, please let us know via a Comment