Oct 23 2009
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
October 23rd, 2009 at 8:34 pm
Thank You for good post about direct-path inserts.
October 25th, 2009 at 3:57 pm
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 …
October 26th, 2009 at 9:55 am
Hi Chris,
see Note 842374.1 for explanation of this behavior.
October 27th, 2009 at 12:55 am
[...] Christian Antognini-Hints for Direct-path Insert Statements [...]
November 3rd, 2009 at 7:16 am
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 ?
November 10th, 2009 at 11:14 pm
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
December 3rd, 2009 at 5:25 pm
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
December 11th, 2009 at 7:33 am
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) violatedCheers,
Chris
December 11th, 2009 at 8:38 am
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
December 15th, 2009 at 12:58 am
Hi Christian,
Are you familiar with SYS_DL_CURSOR hint? Do you know if the APPEND_VALUES hint is functionally the same.
Kerry
December 17th, 2009 at 9:02 am
Hi Kerry
Sorry, I never did tests using the SYS_DL_CURSOR hint.
Cheers,
Chris
November 8th, 2011 at 3:32 pm
[...] statements containing a VALUES clause. Since the time when the book was published, the author created a blog article that demonstrates how to use direct path insert for SQL statements that have a VALUES clause. [...]