Hints for Direct-path Insert Statements

Up to Oracle Database 10g Release 2, direct-path inserts are supported only by INSERT INTO … SELECT … statements (including multitable inserts), MERGE statements (for the part inserting data), and applications using the OCI direct-path interface (for example, the SQL*Loader utility). At the statement level two methods are available to specify that a direct-path insert has to be used:

  • Specify the APPEND hint in the SQL statement
  • Execute the SQL statement (actually, at least the INSERT part) in parallel

Let’s have a look to an example. Notice that:

  • The APPEND hint is used to execute a direct-path insert.
  • The APPEND hint does not work with a “regular” INSERT statement that uses the VALUES clause.
  • To check whether the direct-path insert is performed, the modified table is queried without committing (or rolling back) the transaction. As a result, after a direct-path insert the database engine raises an ORA-12838.
SQL> SELECT * FROM v$version WHERE rownum = 1;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi

SQL> CREATE TABLE t (n NUMBER);

SQL> INSERT /*+ append */ INTO t SELECT 1 FROM dual;

SQL> SELECT * FROM t;
SELECT * FROM t
              *
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

SQL> COMMIT;

SQL> INSERT /*+ append */ INTO t VALUES (2);

SQL> SELECT * FROM t;

         N
----------
         1
         2

Strangely enough, at least for me, in Oracle Database 11g Release 1 the behavior of the APPEND hint has changed. In fact, it is accepted also for a “regular” INSERT statement that uses the VALUES clause. Let’s run the same test as before to illustrate the new behavior.

SQL> SELECT * FROM v$version WHERE rownum = 1;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production

SQL> CREATE TABLE t (n NUMBER);

SQL> INSERT /*+ append */ INTO t SELECT 1 FROM dual;

SQL> SELECT * FROM t;
SELECT * FROM t
              *
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

SQL> COMMIT;

SQL> INSERT /*+ append */ INTO t VALUES (1);

SQL> SELECT * FROM t;
SELECT * FROM t
              *
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

Even more strange, in Oracle Database 11g Release 2 the behavior of the APPEND hint was reverted to the pre-11g one! But, since the feature is really useful in some situations, a new hint called APPEND_VALUES is available. The following example illustrates the new behavior.

SQL> SELECT * FROM v$version WHERE rownum = 1;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

SQL> CREATE TABLE t (n NUMBER);

SQL> INSERT /*+ append */ INTO t SELECT 1 FROM dual;

SQL> SELECT * FROM t;
SELECT * FROM t
              *
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

SQL> COMMIT;

SQL> INSERT /*+ append */ INTO t VALUES (2);

SQL> SELECT * FROM t;

         N
----------
         1
         2

SQL> COMMIT;

SQL> INSERT /*+ append_values */ INTO t VALUES (3);

SQL> SELECT * FROM t;
SELECT * FROM t
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel

10 Comments

  1. October 23, 2009    

    Thank You for good post about direct-path inserts.

  2. October 25, 2009    

    Ciao Chris,

    very interesting – it seems to be useful when the arguments to the VALUES clause are actually arrays according to the docs
    APPEND_VALUES Hint
    In fact I can see no reason to insert-append a single row …

  3. Timur Akhmadeev's Gravatar Timur Akhmadeev
    October 26, 2009    

    Hi Chris,

    see Note 842374.1 for explanation of this behavior.

  4. Raja's Gravatar Raja
    November 3, 2009    

    The exceptions mentioned here for INSERT and APPEND are very useful.

    Please clarify my doubts :
    1. How about using APPEND in other DML Statements like DELETE, UPDATE, MERGE ?
    2. Does PARALLELISM get enabled by default, when APPEND hint is used ?

  5. November 10, 2009    

    Hi Raja

    > How about using APPEND in other DML Statements like DELETE, UPDATE, MERGE ?

    The APPEND hint is only supported for INSERT and MERGE statements. With MERGE statements it is specified as follows:

    MERGE /*+ append */ INTO …

    > Does PARALLELISM get enabled by default, when APPEND hint is used ?

    No. But a parallel insert automatically use direct-path to write data into the blocks…

    Cheers,
    Chris

  6. Houri Mohamed's Gravatar Houri Mohamed
    December 3, 2009    

    Hi Christian,

    Does the dml logging error during insert /*+ append */ select is
    supported by the new oracle release? Particulary for unique and
    primary keys?

    Mohamed

  7. December 11, 2009    

    Hi Mohamed

    DML error logging is not yet supported with direct inserts.

    Here is an example:

    SQL> SELECT * FROM v$version WHERE rownum = 1;
    
    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
    
    SQL> CREATE TABLE t (n NUMBER, pad VARCHAR2(100), CONSTRAINT t_n_uk UNIQUE (n));
    
    SQL> INSERT INTO t VALUES (1,'bla');
    
    SQL> exec dbms_errlog.create_error_log ('t')
    
    SQL> INSERT /*+ append_values */ INTO t VALUES (1,'bla') LOG ERRORS;
    INSERT /*+ append_values */ INTO t VALUES (1,'bla') LOG ERRORS
    *
    ERROR at line 1:
    ORA-00001: unique constraint (CHA.T_N_UK) violated
    
    SQL> SELECT ora_err_mesg$ FROM err$_t;
    
    no rows selected
    
    SQL> INSERT INTO t VALUES (1,'bla') LOG ERRORS;
    INSERT INTO t VALUES (1,'bla') LOG ERRORS
    *
    ERROR at line 1:
    ORA-00001: unique constraint (CHA.T_N_UK) violated
    
    SQL> SELECT ora_err_mesg$ FROM err$_t;
    
    ORA_ERR_MESG$
    --------------------------------------------------------------------------------
    ORA-00001: unique constraint (CHA.T_N_UK) violated

    Cheers,
    Chris

  8. Houri Mohamed's Gravatar Houri Mohamed
    December 11, 2009    

    Thanks Christian,
    Always we learn something new.
    Today is : in 11g we can use direct path insert with insert/values using the hint
    /*+ append_values */
    Regards

  9. December 15, 2009    

    Hi Christian,

    Are you familiar with SYS_DL_CURSOR hint? Do you know if the APPEND_VALUES hint is functionally the same.

    Kerry

  10. December 17, 2009    

    Hi Kerry

    Sorry, I never did tests using the SYS_DL_CURSOR hint.

    Cheers,
    Chris

  1. Blogroll Report 16/10/2009-23/10/2009 « Coskan’s Approach to Oracle on October 27, 2009 at 00:55
  2. Book Review: Troubleshooting Oracle Performance (Part 2) « Charles Hooper's Oracle Notes on November 8, 2011 at 15:32

Leave a Reply

Your email address will not be published. Required fields are marked *