Here is my very first blog post of the year 2019 about a real issue faced by our development team. To make the blog post short and crisp, let me simply dive into the issue.
Problem Statement: I am using APPEND hint with "INSERT INTO SELECT" statement, but when I am trying to SELECT the data after "INSERT INTO SELECT", it is throwing me "ORA-12838: cannot read/modify an object after modifying it in parallel"
First, check what is ORA-12838-
ORA-12838: Cannot read/modify an object after modifying it in parallel
Cause: Within the same transaction, an attempt was made to add read or modification statements on a table after it had been modified in parallel or with direct load. This is not permitted.
Action: Rewrite the transaction, or break it up into two transactions one containing the initial modification and the second containing the parallel modification operation.
Here is the code snippet to reproduce ORA-12838.
As per ORA-12838, Oracle cannot read/modify an object after modifying it in parallel, but we have not used the PARALLEL hint. So we should read about APPEND hint too.
The APPEND hint instructs the optimizer to use direct-path INSERT with the subquery syntax of the INSERT statement.
- Direct-path INSERT is the default in parallel mode.
- In direct-path INSERT, data is appended to the end of the table, rather than using existing space currently allocated to the table. As a result, direct-path INSERT can be considerably faster than conventional INSERT.
- If the table has referential integrity or a trigger, append hint is ignored and Oracle uses the conventional path loading
Now we completely understand "Why INSERT INTO SELECT with APPEND hint is causing ORA-12838". APPEND hint instructs the optimizer to use direct-path INSERT, which is PARALLEL by default and Oracle cannot read/modify an object after modifying it in parallel. The developer was trying to do the same, so before firing the SELECT statement on the TABLE after INSERT INTO SELECT with APPEND hint, he needs to issue a COMMIT which breaks these 2 statements into two transactions.
So now let's try the previous code again, but we will issue the COMMIT before SELECT
Great! it worked. I hope you have Enjoyed reading this post.
Related Links:
- VIEW PUSHED PREDICATE - A Powerful Optimizer Transformation feature
- How to Get Execution Plan and Statistics of SQL Query
- DBMS_PROFILER: How to analyze pl/sql performance
- Top 18 features of Oracle 18c
- Oracle 12c Partitioning New Features - Top 10
- SQL Loader Express Mode - Loading data in Oracle database can't be more easy
Problem Statement: I am using APPEND hint with "INSERT INTO SELECT" statement, but when I am trying to SELECT the data after "INSERT INTO SELECT", it is throwing me "ORA-12838: cannot read/modify an object after modifying it in parallel"
First, check what is ORA-12838-
ORA-12838: Cannot read/modify an object after modifying it in parallel
Cause: Within the same transaction, an attempt was made to add read or modification statements on a table after it had been modified in parallel or with direct load. This is not permitted.
Action: Rewrite the transaction, or break it up into two transactions one containing the initial modification and the second containing the parallel modification operation.
Here is the code snippet to reproduce ORA-12838.
nimish@garg> desc emp
Name Null? Type
------------------------ ------- -------- -----
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
nimish@garg> create table emp_new as select * from emp where 1=2;
Table created.
nimish@garg> insert /*+ APPEND */ into emp_new select * from emp;
14 rows created.
nimish@garg> select * from emp_new where empno = 7839;
select * from emp_new where empno = 7839
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel
As per ORA-12838, Oracle cannot read/modify an object after modifying it in parallel, but we have not used the PARALLEL hint. So we should read about APPEND hint too.
The APPEND hint instructs the optimizer to use direct-path INSERT with the subquery syntax of the INSERT statement.
- Direct-path INSERT is the default in parallel mode.
- In direct-path INSERT, data is appended to the end of the table, rather than using existing space currently allocated to the table. As a result, direct-path INSERT can be considerably faster than conventional INSERT.
- If the table has referential integrity or a trigger, append hint is ignored and Oracle uses the conventional path loading
Now we completely understand "Why INSERT INTO SELECT with APPEND hint is causing ORA-12838". APPEND hint instructs the optimizer to use direct-path INSERT, which is PARALLEL by default and Oracle cannot read/modify an object after modifying it in parallel. The developer was trying to do the same, so before firing the SELECT statement on the TABLE after INSERT INTO SELECT with APPEND hint, he needs to issue a COMMIT which breaks these 2 statements into two transactions.
So now let's try the previous code again, but we will issue the COMMIT before SELECT
nimish@garg> drop table emp_new;
Table dropped.
nimish@garg> create table emp_new as select * from emp where 1=2;
Table created.
nimish@garg> insert /*+ APPEND */ into emp_new select * from emp;
14 rows created.
nimish@garg> commit;
Commit complete.
nimish@garg> select * from emp_new where empno = 7839;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7839 KING PRESIDENT 17-NOV-81 5000.15 10
Great! it worked. I hope you have Enjoyed reading this post.
Related Links:
- VIEW PUSHED PREDICATE - A Powerful Optimizer Transformation feature
- How to Get Execution Plan and Statistics of SQL Query
- DBMS_PROFILER: How to analyze pl/sql performance
- Top 18 features of Oracle 18c
- Oracle 12c Partitioning New Features - Top 10
- SQL Loader Express Mode - Loading data in Oracle database can't be more easy
Using if append will generate huge amount of redo undo logs .. I am not very much sure but I have heard it using append will degrade the performance sometimes .. and one more point we have to disable the nologging mode at the table/db level while making use of append.
ReplyDelete