Home>Question Details



Richer -- Thanks for the question regarding "Append hint in archivelog mode.", version 8.1.7

Submitted on 6-Mar-2003 9:49 Central time zone
Last updated 12-Feb-2007 9:41

You Asked

Hi Tom,

I wanted to test the append hint in an archivelog database.  I wanted to see the 
difference between

-normal insert
-insert with append hint
-insert with append hint and nologging

But I don't see any difference with the redo size generated by the 3 different options.  
I thought inserting with the append hint and by asking nologging would generate 
significantly redo.  What am I seeing wrong?

--------------------------------------------------------

SQ90084@MAGPROD> TRUNCATE TABLE TEST;

Table truncated.

Elapsed: 00:00:00.00
SQ90084@MAGPROD> INSERT INTO TEST SELECT * FROM DBA_OBJECTS;

7535 rows created.

Elapsed: 00:00:00.04
SQ90084@MAGPROD> SELECT * FROM V$MYSTAT WHERE STATISTIC# =101;

       SID STATISTIC#      VALUE
---------- ---------- ----------
        17        101   11299716

Elapsed: 00:00:00.00
SQ90084@MAGPROD> TRUNCATE TABLE TEST;

Table truncated.

Elapsed: 00:00:00.01
SQ90084@MAGPROD> INSERT /*+ APPEND */  INTO TEST SELECT * FROM DBA_OBJECTS;

7535 rows created.

Elapsed: 00:00:00.05
SQ90084@MAGPROD> SELECT * FROM V$MYSTAT WHERE STATISTIC# =101;

       SID STATISTIC#      VALUE
---------- ---------- ----------
        17        101   12110516

Elapsed: 00:00:00.00
SQ90084@MAGPROD> TRUNCATE TABLE TEST;

Table truncated.

Elapsed: 00:00:00.00
SQ90084@MAGPROD> INSERT /*+ APPEND */  INTO TEST SELECT * FROM DBA_OBJECTS NOLOGGING;

7535 rows created.

Elapsed: 00:00:00.05
SQ90084@MAGPROD> SELECT * FROM V$MYSTAT WHERE STATISTIC# =101;

       SID STATISTIC#      VALUE
---------- ---------- ----------
        17        101   12921700

Elapsed: 00:00:00.00 

and we said...

your NOLOGGING isn't NOLOGGING.  that last insert is really not any different then:

INSERT /*+ APPEND */  INTO TEST SELECT * FROM DBA_OBJECTS HI_THERE;

nologging is just a table alias in that context.  you MEANT alter table.  

Here we go, in archive log mode database, using the infinitely easier autotrace:

ops$tkyte@ORA9I> drop table t;
Table dropped.

ops$tkyte@ORA9I> create table t as select * from all_objects where 1=0;
Table created.

ops$tkyte@ORA9I> set autotrace on statistics
ops$tkyte@ORA9I> insert into t select * from all_objects;

44876 rows created.


Statistics
----------------------------------------------------------
        334  recursive calls
       3528  db block gets
     408390  consistent gets
       3729  physical reads
    4980348  redo size
        786  bytes sent via SQL*Net to client
        808  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
      44876  rows processed

ops$tkyte@ORA9I> commit;

Commit complete.

ops$tkyte@ORA9I> insert /*+ APPEND */ into t select * from all_objects;

44876 rows created.


Statistics
----------------------------------------------------------
        227  recursive calls
        151  db block gets
     407437  consistent gets
       2369  physical reads
    5081144  redo size
        772  bytes sent via SQL*Net to client
        822  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      44876  rows processed

ops$tkyte@ORA9I> commit;

Commit complete.

no difference - in archive log, append surpressed ROLLBACK but NOT redo, so...

ops$tkyte@ORA9I> ALTER TABLE T NOLOGGING;

Table altered.

ops$tkyte@ORA9I> insert /*+ APPEND */ into t select * from all_objects;

44876 rows created.


Statistics
----------------------------------------------------------
        411  recursive calls
        136  db block gets
     407471  consistent gets
       1586  physical reads
      14608  redo size
        773  bytes sent via SQL*Net to client
        822  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
      44876  rows processed

ops$tkyte@ORA9I> commit;

Commit complete.

ops$tkyte@ORA9I> set autotrace off


there you go, redo way down (but time for me to go off and backup my database since I 
broke the redo chain for these blocks!)

 

Reviews    
5 stars How didn't I see that!   March 6, 2003 - 4pm Central time zone
Reviewer: Rich 
Sorry for a stupid question.  It was so obvious it almost got me blind...

 


5 stars Rollback   March 6, 2003 - 6pm Central time zone
Reviewer: Peter 
"no difference - in archive log, append surpressed ROLLBACK but NOT redo, "

Tom what is showing you that ROLLBACK was supressed?? 


Followup   March 6, 2003 - 6pm Central time zone:

I know it was, that is why :)

Here is the "tangible evidence"

ops$tkyte@ORA9I> create table t as select * from all_objects where 1=0;

Table created.

ops$tkyte@ORA9I>
ops$tkyte@ORA9I> insert into t select * from all_objects;

44876 rows created.

ops$tkyte@ORA9I> select used_ublk
  2    from v$transaction
  3   where addr = ( select taddr from v$session where sid =
  4                    ( select sid from v$mystat where rownum = 1 )
  5                 );

 USED_UBLK
----------
        22

ops$tkyte@ORA9I> commit;

Commit complete.

ops$tkyte@ORA9I>
ops$tkyte@ORA9I> insert /*+ APPEND */ into t select * from all_objects;

44876 rows created.

ops$tkyte@ORA9I> select used_ublk
  2    from v$transaction
  3   where addr = ( select taddr from v$session where sid =
  4                    ( select sid from v$mystat where rownum = 1 )
  5                 );

 USED_UBLK
----------
         1

ops$tkyte@ORA9I> commit;

Commit complete.


That is what append does.  It writes above the HWM of the table, bypassing the need for rollback.  
That is why you cannot query the table after a direct path insert without committing -- it sort of 
"breaks" our consistent read mechanism for that session on that table.

rollback for inserts is very very small (delete rowid is all that is made)...

 

5 stars Excellent. But why doesn't oracle allow you to read the rows you just inserted?   March 6, 2003 - 8pm Central time zone
Reviewer: gs 
Tom,

I was always wondering, why oracle doesn't allow to read the data inserted thru "direct insert" 
without doing a commit?

Is it because, oracle doesn't have any info on this insert in the RBS? But how come, it allows me 
to read after "commit"? 


Followup   March 7, 2003 - 7am Central time zone:

We don't have the information needed in the RBS for our consistent read mechanism to work (as 
stated above).

...
That is what append does.  It writes above the HWM of the table, bypassing the 
need for rollback.  That is why you cannot query the table after a direct path 
insert without committing -- it sort of "breaks" our consistent read mechanism 
for that session on that table
......


Insert /*+APPEND*/ is a "special" thing, a tool that you may or may not choose to use.  It does 
what it does. 

4 stars If rollback generation was surpressed then why we got the same amount of redo?   March 7, 2003 - 1pm Central time zone
Reviewer: Dmitry from NH
Hi Tom,

You wrote in the middle of the first reply:

*no difference - in archive log, append surpressed ROLLBACK but NOT redo,* 

If rollback generation was surpressed then why we got the same amount of redo as without append? 
My understanding (from your book actually) was that redo protects *both data blocks and rollback 
entries*. As we do not have rollback for the operation we should get less redo. Why the numbers are 
the same?

Thank you, 
 


Followup   March 7, 2003 - 1pm Central time zone:

because in the insert we generated

21 blocks of undo without append
 1 blocks of undo with append

and CREATED 

ops$tkyte@ORA9I> analyze table t compute statistics for table;

Table analyzed.

ops$tkyte@ORA9I> select blocks from user_tables where table_name = 'T';

    BLOCKS
----------
      1228


new blocks.


So, in one case we had redo for 1249 blocks, in the other case 1229 blocks.  

No significant difference there.....  that is why the same amount of redo was generated more or 
less -- we had about the same amount of blocks to log redo for.



 

5 stars Excellent   March 7, 2003 - 4pm Central time zone
Reviewer: Dmitry from NH
Yes, number of generated undo blocks times less than created data block. That's why the difference 
in redo is not significant.

Thank you, 


4 stars SQL Loader Direct Insert and Append Hint Difference   March 14, 2003 - 7am Central time zone
Reviewer: Nurlan from Kazakhstan
Hello Tom, let me continue the discussion. The question is whether any difference between SQL 
Loader Direct Insert and Insert with the Append Hint.  
... SQL*Loader then uses the column array structure to format Oracle data blocks and build index 
keys. The newly formatted database blocks are then written directly to the database (multiple 
blocks per I/O request using asynchronous writes if the host platform supports asynchronous I/O). 
Is there anything like this for Inserts with append hint? 
Namely, will such inserts skip the buffer cache or any preprocessing? I did not find anything on 
any differences, but they are called the same, direct inserts, or loads. 


Followup   March 14, 2003 - 6pm Central time zone:

they are not 100% the same but are for all intents and purposes "so similar as to be not really 
distinguisable by us".

direct path inserts also do direct io. 

4 stars testing   June 19, 2003 - 2pm Central time zone
Reviewer: sam from NY USA
Tom I did some testing as follows

CREATE TABLE A1 unrecoverable parallel (degree 30)
tablespace sdmuser01
as
select Cust_num , 'PFS' as PFS_CD from tdmcustinsight a
where  a.rm_lob_code = '03'
and a.pfs_offer_code is not null
/

Elapsed: 00:00:05.66

No rollback .

insert into a1 (cust_num,PFS_CD)
select Cust_num , 'PFS' as PFS_CD from tdmcustinsight a
where  a.rm_lob_code = '03'
and a.pfs_offer_code is not null
/


Elapsed: 00:00:14.81

Statistics
----------------------------------------------------------
    9313840  redo size
     366527  rows processed

rollback usage 

NAME           USED_KB   SID   PID SPID 
R08                896    67   118 15906     

insert /*+ APPEND */ into a1 (cust_num,PFS_CD)
select Cust_num , 'PFS' as PFS_CD from tdmcustinsight a
where  a.rm_lob_code = '03'
and a.pfs_offer_code is not null
/

Elapsed: 00:00:12.45

Statistics
----------------------------------------------------------
      13760  redo size
     366527  rows processed

NAME           USED_KB   SID   PID SPID      
R05                 16    67   118 15906     


CREATE TABLE A1 
tablespace sdmuser01
as
select Cust_num , 'PFS' as PFS_CD from tdmcustinsight a
where  a.rm_lob_code = '03'
and a.pfs_offer_code is not null
/

Elapsed: 00:00:10.46


insert into a1 (cust_num,pfs_Cd)
select Cust_num , 'PFS' from tdmcustinsight a
where  a.rm_lob_code = '03'
and a.pfs_offer_code is not null
/

Elapsed: 00:00:13.11

Statistics
----------------------------------------------------------
    9427752  redo size
     366527  rows processed

NAME           USED_KB   SID   PID SPID      
R04                896    67   118 15906     

insert /*+ APPEND */ into a1 (cust_num,pfs_Cd)
select Cust_num , 'PFS' from tdmcustinsight a
where  a.rm_lob_code = '03'
and a.pfs_offer_code is not null
/

Elapsed: 00:00:12.43

Statistics
----------------------------------------------------------
      36104  redo size
     366527  rows processed

NAME           USED_KB   SID   PID SPID      
R01                 16    67   118 15906     

Couple of questions.
When we create a table there is lot of difference in time as against we insert or insert with 
append hint.
Why is that?? 
   If the answer is no REDO & ROLLBACK , the numbers don't justify the difference.

But if we  compare the timing between normal table creation (Without unrecoverable option) & insert 
then elapsed time 
are more meaningful.

So exactly what happens with unrecoverable option ??
Also can you show some light (or link) on parallel option for table creation.

Also if such a minimal rollback is created with append option how we can rollback transaction 
successfully ???

Thanks 


Followup   June 20, 2003 - 3pm Central time zone:

a couple of seconds wall clock difference is not meaningful -- you are taking like 2 seconds on the 
wall clock.

check out the concepts guide, chapter on parallel operations.

read the chapter near the parallel stuff on direct path operations for information on APPEND 
(append writes straight to disk, bypasses the buffer cache and writes ABOVE the current high water 
mark for the table -- hence, if you need to rollback, we simply put the HWM back -- data 
"disappears" 

4 stars testing   June 20, 2003 - 4pm Central time zone
Reviewer: sam from NY USA
"a couple of seconds wall clock difference is not meaningful -- you are taking 
like 2 seconds on the wall clock."

What do u mean by that??

Also let me rephrase my question.

If we don't care about redo generation (In read intensive data warehouse) should it be standard 
practice to insert data using /*+ APPEND */ hint ??

When I say only 2 sec difference what I was referring to was it's not that great as compared to 
create table with unrecoverable option.
create table 05.66
insert append 12.45
insert normal 14.81

I was expecting insert append timings would be closer to create table timings. Can you throw some 
light ??

Meantime I am going through concept guide too.

Sam






 


Followup   June 20, 2003 - 5pm Central time zone:

I mean, in the grand scheme of things -- 2 seconds between 10 and 12 seconds is "noise".  

maybe the disks spun slower.
maybe someone else was doing something.
your query ran faster one time, slower the next time.

everything will affect that time.  You need to use tracing and tkprof to see what's up there.

In a data warehouse, during bulk loads, you can definitely use this feature as long as you BACKUP 
right afterwards.  You can use this in any situation -- as long as you BACKUP.

I just don't observe what you do:

create table t NOLOGGING as select * from all_objects

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.01          0          0          0           0
Execute      1      4.23       4.34          0     146054        522       31578
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      4.24       4.36          0     146054        522       31578

insert into t select * from all_objects


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.08          0          0          0           0
Execute      1      4.10       4.79          0     146487       4326       31578
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      4.11       4.88          0     146487       4326       31578


insert /*+ APPEND */ into t select * from all_objects


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.06          0          0          0           0
Execute      1      4.04       4.12          0     146050        123       31578
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      4.05       4.18          0     146050        123       31578



so, I just put it down to "you have other things going on on your system, they are affecting you, 
things will run slower and faster depending on who is doing what".




 

5 stars   February 9, 2007 - 9am Central time zone
Reviewer: A reader 
HI Tom,

  If I issue

inset /*+ append */ into test select * from test@other_db;
commit;

  Assume about 10,000,000 records loaded. If I later issue:

  select * from test, testB where test.A = testB;

  And later "snapshot too old" error reported, does this mean that the error is not related with table test, and only related with table testB (since append suppress rollback)?

Thanks
David

Followup   February 9, 2007 - 9am Central time zone:

"it depends"


did test have data from before.
indexes on test being used (append relates to the table segment only).


"probably" was testb, likely.
5 stars   February 9, 2007 - 9am Central time zone
Reviewer: A reader 
Hi Tom,

  But if

1. No record in test
2. insert /*+ append */ into test select * from test@other_db;
3. 10,000,000 records loaded.
4. commit;
5. Build indexes (nologging) on test
6. select * from test, testB where test.A = testB.A;

And later "snapshot too old" error reported, does this mean that the error is not related with table test, and only related with table testB (since append suppress rollback)?

Thanks
David


Followup   February 12, 2007 - 8am Central time zone:

it is not so much that append surpressed undo as append did a direct path (clean blocks) load and block cleanout would not be necessary.

probably it was testB that was the cause, yes, but we already stated that.
5 stars   February 9, 2007 - 5pm Central time zone
Reviewer: Eric from Cincinnati, OH
Previous post...

"And later "snapshot too old" error reported, does this mean that the error is not related with table test, and only related with table testB (since append suppress rollback)?"

The rollback suppression is only relevant to your direct path insert. Post-commit, if both tables are subject to DML, each table's blocks are potentially subject to rollback entries? If users start modifying data in TEST and/or TESTB after your insert then your ORA-1555 could be a result of DML against either table, right?

Followup   February 12, 2007 - 9am Central time zone:

yes, "probably" this was testb in this particular case.
5 stars   February 9, 2007 - 11pm Central time zone
Reviewer: A reader 
Hi,

In my case, there is no DML on table TEST after the direct-loading. Moreover, I issue "select count(*) from TEST" after the direct-loading. However, the "snapshot too old" still reported. I want to know is this only related with the other table or with table TEST (TEST has 3 indexes).

Thanks





Write a Review
 


All information and materials provided here are provided "as-is"; Oracle disclaims all express and implied warranties, including, the implied warranties of merchantability or fitness for a particular use. Oracle shall not be liable for any damages, including, direct, indirect, incidental, special or consequential damages for loss of profits, revenue, data or data use, incurred by you or any third party in connection with the use of this information or these materials.

About Oracle | Legal Notices and Terms of Use | Privacy Statement