Skip to Main Content
  • Questions
  • Soft parsing of a procedure call (begin ... end;)

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Alexander.

Asked: July 09, 2007 - 9:02 am UTC

Last updated: April 23, 2008 - 4:56 pm UTC

Version: 9.2.0.7

Viewed 1000+ times

You Asked

Hi Tom,

we have a serious contention for the library cache latch in our production db.
I'm trying to find SQLs that are being parsed most intensively.
Below is the SQL
that is parsed most frequently (from statspack report).

Further, I have traced a couple of sessions mostly
waiting for latch free and see that similar procedure calls behave differently
from the parsing point of view: some are parsed every time when executing,
some are parsed only once. Could you give me a clue why, what's the difference
between them and is there anythingthe coders can do to force "bad" calls
to be parsed once.

And is this the right way of reducing the library cache latch contention?

TIA,
Alexander

                           % Total
 Parse Calls  Executions   Parses  Hash Value
------------ ------------ -------- ----------
     438,213      438,250     5.98 3352235821
Module: ModuleName
begin :msg:=IBS.executor.get_pipe_text(:pipe);end;

********************************************************************************

BEGIN Z#MAIN_DOCUM#INTERFACE.LOCK_OBJECT(:OBJ_ID,:INFO,:CLASS,:WAIT); END;


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse      421      0.05       0.50          0          0          0           0
Execute    421      0.82       3.32          0        522        179         421
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      842      0.87       3.82          0        522        179         421

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23     (recursive depth: 1)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  latch free                                    373        0.16          2.62
  library cache pin                               4        0.00          0.00
********************************************************************************

BEGIN Z$DOCUM_RC_TR_1.TR_1_EXECUTE(:OBJ_ID,:CLASS); END;


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse      414      0.10       0.88          0          0          0           0
Execute    414      2.23      15.91          7       6419        874         414
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      828      2.33      16.79          7       6419        874         414

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23     (recursive depth: 1)

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  latch free                                   1384        0.43         13.06
  wait list latch free                            3        0.02          0.05
********************************************************************************


begin
:GDT_MYOUTPUT:=IBS.EXECUTOR.GET_DEBUG_TEXT(:GDT_DIRECTION);
END;

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      8      0.02       0.45          0          5          3           8
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        8      0.02       0.45          0          5          3           8

Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 284  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  latch free                                     41        0.05          0.60
  SQL*Net message to client                       8        0.00          0.00
  SQL*Net more data to client                     3        0.00          0.00
  SQL*Net message from client                     8       54.00         75.63
********************************************************************************

begin
:LOCK_RES := IBS.executor.lock_request(:LOCK_NAME, 'Nav', :TIME_OUT);
END;

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        2      0.00       0.00          0          0          0           0
Execute    138      0.63       4.75          0         61          3         138
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      140      0.63       4.76          0         61          3         138

Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 284  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                     146        0.00          0.00
  SQL*Net message from client                   146        1.27          1.48
  latch free                                    444        0.11          4.78
  wait list latch free                           10        0.02          0.19
  pipe get                                        4        0.43          0.45
  library cache pin                               3        0.00          0.01
********************************************************************************

and Tom said...

we parse when a developer says "PARSE THIS ORACLE"

we do not parse when they do not ask us to do that.


it is entirely up to the coder - they either:

a) parse
b) bind
c) execute
d) close

a statement over and over and over again or they:

a) ask if they already parsed this
a-prime) if not, parse it and remember they did

b) bind
c) execute



The developers can use language specific features like jdbc statement caching:
http://www.oracle.com/technology/products/oracle9i/daily/jun24.html

if applicable as well...

but, this ultimately can only be corrected entirely in the application itself (session_cached_cursors can *help* but not remove the problem, an init.ora parameter)


and yes, over parsing (hard or soft) is a major scalability inhibitor.

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Consistent Gets - Group By

Steve, July 13, 2007 - 10:12 am UTC

Hi Tom

I am a fan of your site. Over the years i have learned many tricks and useful things in this site.
I am currently struggling with a query with Group By clause.

The query takes about 13 minutes to bring back all the rows.

When i observe the V$SQLAREA view for the time taken by the query, till about 12 minutes the ROWS_PROCESSED is 0 and suddenly in the last minute (13th minute) 329000 records are processed. The number of Buffer Gets at the end are 8.5 million.

Why does it not retrieve the data till the 12th minute?

Thanks in advance for your quick response.

Regards
Steve
Tom Kyte
July 13, 2007 - 10:42 am UTC

must be writing to temp. group bys many times cannot return the first row until the last row is produced.

Soft Parsing and Connection Pooling

Dries Verbeke, April 21, 2008 - 8:11 am UTC

Tom,
what is the effect on parsing when working with connection pools? I read somewhere that the soft parse is at least done once per session. But I 'm not sure how this works when you pool your connections.
We use connection pooling in our web application. The application performs a couple queries per request and therefore it open (or get a connection from the pool) and closes again the connection (returns to the pool). But if the documentation is right, is it also correct to assume that the soft parse will be executed for every request? whatever I do on the application side? Or does oracle persist the cursor over different sessions?

And then the real stupid questions! Why does oracle only cache the hard parse and not the soft parse? Why does the application layer need to be concerned with this database specific performance issue? Is this a marketing option to promote the use of pl/sql and by doing this locking in the oracle database and loosing the database independence? Or are there exception where you want to have a soft parse and not a hard parse?

Thanks
Dries
Tom Kyte
April 23, 2008 - 4:56 pm UTC

use jdbc statement caching - it'll make jdbc work a little like plsql (but never as cool as plsq).

why would we cache a soft parse? if you close a cursor programatically in a 3gl, you obviously meant "close it" didn't you....

If not, session_cache_cursors can help a but, but there is still a lot of work involved in connecting your session back up with the sql in the shared pool (session cached cursors can make a soft parse a softer soft parse)


But look into jdbc statement caching.

@ Dries Verbeke re: Soft Parsing and Connection Pooling

Stew Ashton, April 29, 2008 - 10:21 am UTC


Dries, as you look into JDBC statement caching, you will find that each pooled connection has its own statement cache. Therefore, you should find that there will be one hard parse the first time the statement is executed in the instance, then one soft parse for every new connection.

So don't be surprised if you see more than one parse call during your testing.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library