In the past few days I've playing around with Oracle's SQL*Loader in attempt to bulk load data into Oracle. After trying out different combination of options I was surprised to found the conventional path load runs much quicker than direct path load.
A few facts about the problem:
- Number of records to load is 60K.
- Number of records in target table, before load, is 700 million.
- Oracle version is 11g r2.
- The data file contains date, character (ascii, no conversion required), integer, float. No blob/clob.
- Table is partitioned by hash. Hash function is same as PK.
- Parallel of table is set to 4 while server has 16 CPU.
- Index is locally partitioned. Parallel of index (from ALL_INDEXES) is 1.
- There's only 1 PK and 1 index on target table. PK constraint built using index.
- Check on index partitions revealed that records distribution among partitions are pretty even.
- Data file is delimited.
- APPEND option is used.
- Select and delete of the loaded data through SQL is pretty fast, almost instant response.
With conventional path, loading completes in around 6 seconds.
With direct path load, loading takes around 20 minutes. The worst run takes 1.5 hour to complete yet server was not busy at all.
If skip_index_maintenance is enabled, direct path load completes in 2-3 seconds.
I've tried quite a number of options but none of them gives noticeable improvement... UNRECOVERABLE, SORTED INDEXES, MULTITHREADING (I am running SQL*Loader on a multiple CPU server). None of them improve the situation.
Here's the wait event I kept seeing during the time SQL*Loader runs in direct mode:
- Event: db file sequential read
- P1/2/3: file#, block#, blocks (check from dba_extents that it is an index block)
- Wait class: User I/O
Does anyone has any idea what has gone wrong with direct path load? Or is there anything I can further check to really dig the root cause of the problem? Thanks in advance.