Seems I have found answer my own question :
First - let me reword my question :
"Under exactly same environment and conditions" - Some users are complaining that same SQL which runs in few seconds takes over an hour, when same SQL is made part of a PL/SQL procedure or package.
The key words here are "same conditions and environment". The Oracle Version is 12.1.0.2.0. The table, row count, operation, statistics etc. are same for both (SQL and PL/SQL).
Here is a quick test.
The statement I choose is straight update - so practically no network or terminal display delay
- Create a table with say 200,000 rows. ( No indexes etc. whatsoever ).
- Turn on SQL_TRACE = ON at server level
SQL : a. update stats b. set timing on
Update TABLE_1 set Character_Col = 'XXXX';
PL/SQL :
a. update stats
create or replace procedure upd_tab as
begin
update TABLE_1 set Character_Col = 'XXXX';
dbms_output ( .. print SQL%ROWCOUNT etc. );
end;
When comparing the TRACE, the significant difference is found in the Execute part of trace
SQL :
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Execute 1 2.19 2.40 0 1902 257114 200000
PL/SQL:
call count cpu elapsed disk query current rows
Execute 1 2.13 5.94 0 1884 256912 200000
So - what I can understand is that there is CONTEXT-SWITCHING taking place when PL/SQL sends statement to SQL. When statement is directly executed as SQL, then no context switching is involved.
It seems my end-users are using cursors to send one UPDATE statement at a time to database from a stored procedure. And for 100,000+ rows, these few seconds are quickly adding up.
It reminds me of Tom Kyte's famous words ( not exactly; hope somebody can find the link )
if you want to do something, do it in SQL,
if SQL is not suitable, then do it in PL/SQL,
if PL/SQL is not suitable, then do it as Java,
if Java is not suitable, then do it as External C procedure,
if External C is not suitable, then think - why we have to do it in first place.