Tuesday, April 1, 2008

Oracle INSERT Performance

Yesterday we had an issue to increase the speed of insert statements. We had to insert about 500K record to database as quickly as possible. We were inserting at a rate of 10 records/sec. Well, I was thinking the following approaches to gain speed-

1. Use a large blocksize - By defining large (i.e. 16k or 32k) blocksizes for the target tables, we can reduce I/O because more rows fit onto a block before a “block full” condition (as set by PCTFREE) unlinks the block from the freelist.

>DROP TABLESPACE web_key_tbs INCLUDING CONTENTS AND DATAFILES;
>CREATE TABLESPACE web_key_tbs DATAFILE ‘/mnt/extra/test1.dbf’ SIZE 1024M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED blocksize 16K;

2. Increase the size of UNDO tablespace -

>CREATE UNDO TABLESPACE UNDOTBS DATAFILE ‘/mnt/extra/test_undo1.dbf’ SIZE 200M BLOCKSIZE 16K;
>alter system set undo_tablespace=’UNDOTBS‘ scope=both;
>DROP TABLESPACE UNDOTBSP1 INCLUDING CONTENTS AND DATAFILES;

3. APPEND into tables - By using the APPEND hint, it ensures that Oracle always grabs fresh data blocks by raising the high-water-mark for the table.

>insert /*+ append */ into customer values (’hello’,';there’);

4. Table into NOLOGGING mode - Putting the table into NOLOGGING mode, which will allow Oracle to avoid almost all redo logging.

>SELECT logging FROM user_tables WHERE table_name = ‘LOGIN’;
>ALTER TABLE login NOLOGGING;

Again, to enable logging -
>ALTER TABLE login LOGGING;

5. Disable/drop indexes - It’s far faster to rebuild indexes after the data load, all at-once. Also indexes will rebuild cleaner, and with less I/O if they reside in a tablespace with a large block size.

6. Parallelize the load - We can invoke parallel DML (i.e. using the PARALLEL and APPEND hint) to have multiple inserts into the same table. For this INSERT optimization, make sure to define multiple freelists and use the SQL “APPEND” option.

Unfortunately I could not be able to apply all the tricks as the insertions were done by a third party application. I only tried the first two options - it did not help :(. I could not even managed to analyze the wait events for the exact reason of waiting. That third party software, which did insert operations, uses Oracle Call Interface (OCI) - so statements were not available to the database.

One more thing- database was runnnig in NOARCHIVELOG mode.

2 comments:

  1. The append hint is useless (not taken into account) unless used with a subquery -- thus your recommendation to use >insert /*+ append */ into customer values (’hello’,';there’);

    is incorrect -- hint is ignored -- conventional is insert used -- I see people assume this many times -- Even Burleson Consulting has got it wrong on one of his websites

    ReplyDelete
  2. Hey, earlier I have seen similar post to other blogs ;)

    ReplyDelete