Pedro Oliveira, May       02, 2001 - 7:15 am UTC
 
 
  
 
Sean, May       26, 2001 - 11:25 pm UTC
 
 
  
 
review of bstat/estat question
Wayne, September 07, 2001 - 9:26 am UTC
 
 
Tom,
  The query you gave in your answer sheds good light on tuning using the bstat/estat utilities.
Wayne 
 
 
Performance stuff
Tania Wroe, December  11, 2001 - 2:12 am UTC
 
 
Excelent 
 
 
anxious to try this out
A reader, April     30, 2002 - 2:25 pm UTC
 
 
I have been trying to understand what is behind my extremely high library cache hit ratio (99.5%), yet relatively poor gethitratio of 60%.  From what I read no physical db tuning would improve the gethitratio since there was plenty of free memory for the shared pool. 
 
 
Error while processing 
Raman Pujani, May       24, 2002 - 5:24 am UTC
 
 
Hi Tom,
Most of the time when I run remove_constant and the query to generate report, I get :
update t1 set sql_text_wo_constants = remove_constants(sql_text)
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
What could be the reason ?
Regards,
Raman. 
 
May       24, 2002 - 9:31 am UTC 
 
Please contact support -- it will be a bug, you may require a patch.  I've never seen that behaviour myself.
There will be a trace file on the server they will need to diagnose this issue.
meanwhile, you can do something like:
declare
  l_tmp long;
begin
  for x in ( select rowid rid, sql_text from t1 ) 
  loop
     l_tmp := remove_constants( x.sql_text );
     update t1 set sql_text_wo_constants = l_tmp where rowid = x.rid;
   end loop;
end;
/
instead of the single update.
       
 
 
 
Can you please explain ?
A reader, June      21, 2002 - 10:03 am UTC
 
 
Hi tom ,
 the solution/work around, you have given above, does it 
use the bind variables ?
  beacause I don't know yet, after all your explanation in all questions and your book 
the difference between the cursor variable and bind variable
 I think can we use the bind variable in the following way 
will the performance better ?
/********************************************/
declare
  l_tmp long;
begin
  open  x for 
   'select rowid rid, sql_text from t1' --returns 10000 rows
  loop
     l_tmp := remove_constants( x.sql_text );
      execute immediate
    'update t1 set sql_text_wo_constants=:a where rowid  :y'
     using remove_constants( x.sql_text ),x.rid
   end loop;
end;
/
/*********************************************/
 could you please explain. Tankans.. 
 
 
June      21, 2002 - 1:13 pm UTC 
 
NO -- that would be a terribly slow, bad way to do it. 
It violated my rule #1
a) if you can do it in single SQL statment -- DO IT.
All of the code above makes 100% use of bind variables where appropriate.  When considering "have I done this bind variable thing right" you only need look at the sql statement:
update t1 set sql_text_wo_constants = remove_constants(sql_text);
and then ask "will I ever submit a statement that looks ALMOST exactly like that except that some constant has changed?"
The answer in this case is "definitely NOT, there aren't even any constants in there".
When you see queries like:
update t set x = 5 where y = 2;
update t set x = 6 where y = 1;
update t set x = 8 where y = 43;
Those statements demand bind variables.  That should be a single statment:
update t set x = :x where y = :y;
that is executed with different inputs.  As my update:
update t1 set sql_text_wo_constants = remove_constants(sql_text);
has no constants -- there are thusly NO binds to be done. 
 
 
 
Tom, that is excellent!
Sanjay, June      21, 2002 - 1:33 pm UTC
 
 
Could you clarify further as how to rad the output from query to make out whether bind variables are being used or not?
SQL> /
Function created.
SQL>  update t1 set sql_text_wo_constants = remove_constants(sql_text);
276 rows updated.
SQL> select sql_text_wo_constants, count(*)  from t1 group by sql_text_wo_constants
  2  having count(*) > 100 order by 2;
no rows selected
SQL> /
no rows selected
SQL> 2
  2* having count(*) > 100 order by 2
SQL> c/100/5
  2* having count(*) > 5 order by 2
SQL> /
SQL_TEXT_WO_CONSTANTS
--------------------------------------------------------------------------------
  COUNT(*)
----------
SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OBJECT_ID = @
        92
What does @ mean here? 
 
 
June      21, 2002 - 2:33 pm UTC 
 
That means you have 92 copies of the statement in the shared pool and the ONLY difference between them is the number in the object_id = 
My remove constants turns any character string literal into '#' and any number into @.  It then counts how many statements are in the shared pool that are the same EXCEPT for the constants.
If you 
select sql_text from v$sql where upper(sql_text) like 'SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OBJECT_ID%'
you'll see what i mean. You have someone NOT using bind variables in all likelyhood. 
 
 
 
ORA-03113
Harrison Picot, June      21, 2002 - 5:22 pm UTC
 
 
    ORA-03113: end-of-file on communication channel
I am sorry that I can't remember the context, but I have
seen that message in relation to some kind of a space
problem.  It wasn't an Oracle bug it was my bug. I can't
remember more about it than that, but I remember thinking
that it was "obvious" after I found it.  Sorry this is so
vague, but had I called Oracle support, I'm not sure that
message would trigger an answer to the problem I had. At
the time I thought my database had been corrupted by 
lightening, and restored from backups, but when I got to
same point again, I got the same error and that was when
the light went on.  Anyway, this can just be a warning that
ORA 03113 is not a clear message, so checking your logs
(as Tom suggests) will worth a lot more than that error. 
 
 
Can you explain this ?
A reader, June      24, 2002 - 9:49 am UTC
 
 
Hi tom,
 Thanks, for your answer.
I would like to still ask you one question on this bind variable thing.
 Now as you've explained me
1.) if I can do it in one stmt. I should do it.
Ok, my qustion is in your followup answer
/***************************************************/
Followup:  
Please contact support -- it will be a bug, you may require a patch.  I've never 
seen that behaviour myself.
There will be a trace file on the server they will need to diagnose this issue.
meanwhile, you can do something like:
declare
  l_tmp long;
begin
  for x in ( select rowid rid, sql_text from t1 ) 
  loop
     l_tmp := remove_constants( x.sql_text );
     update t1 set sql_text_wo_constants = l_tmp where rowid = x.rid;
   end loop;
end;
/
instead of the single update.
       
/********************************************************/
 don't  we have the same situation where
we are saying
 update t set x =  l_tmp where y = x.rid
isn't it same as
 update t set x = 4  where y = 5
 so won't the sql stmt will distinct at run time 
it be executed the # of rows time ?
are we using bind varible ? if yes how ?
if not, then in this case, will it be better to use bind 
using the execute immedieate ?
 Plese explain..
thanks in advence 
 
 
 
June      24, 2002 - 9:52 am UTC 
 
No, it is not.  I am using host variables.  The statement:
update t1 set sql_text_wo_constants = l_tmp where rowid = x.rid;
is really:
pdate t1 set sql_text_wo_constants = :BV1 where rowid = :BV2;
anywhere there is a PLSQL variable -- it is really a host variable, a bind variable.  That is part of the beauty of PLSQL -- it makes binding almost MOOT.  You have to absolutely go out of your way to NOT bind in plsql.
 
 
 
 
Thanks Tom
A reader, June      24, 2002 - 10:43 am UTC
 
 
Hi Tom,
 Thanks, for clearing this up for me.
 Now I feel comfortable with this bind variable and cursor variables, as you've acknoledged that pl/sql cursor variable/ plsql variable is it self a bind/host variable.
  I will further investigate and explore this becacuse I know I have seen some illustration where in the pl/sql block
where we can use the pl/sql varable, dynamic stmt is used.
 I think from my point of view almost all statement can be written using pl/sql variable ( DDL stmt excluded). but I will investigate further ...
thanks..
  
 
 
Regarding ORA-03113
Colin Davies, June      24, 2002 - 3:56 pm UTC
 
 
I just ran into this over the weekend while building a new instance on a new server.  It was apparently the result of not having enough semaphores.
When I reduced the PROCESSES parameter in the init.ora file to 50, the error went away; when I raised it, it came back.  We adjusted the kernel parameters in the /etc/system file, rebooted the server, and everything was fine again. 
 
June      25, 2002 - 8:35 am UTC 
 
Well, let me say something about the 3113 error.
It means "something went wrong, we died".
It can be caused by literally thousands and thousands of things.  It is a very generic error message.
A crash (segmentation fault) in the server process could cause it.
Not enough semaphores can cause it (but only on startup, not later).
Network errors can cause it.
and so on.  
There is no single answer to "what causes a 3113".
If you look up support note  <Note:19790.1>  on metalink, you'll see:
Explanation:
        There are numerous causes of this error. It is a 'catch all' type 
        error which means 'I cannot communicate with the oracle shadow process'.
        This usually occurs when the Oracle server process has died for
        some reason.
Diagnosis:
        Oracle support need more information to determine what caused the
        error. The most useful items are:
        1) Does this occur when trying to (a) make a connection to the 
           database or (b) on an established connection ?
        2) There should be a trace file from the failed session in 
           USER_DUMP_DEST
        3) Does a particular statement reproduce this problem or is it
           random ? Use SQL_TRACE on the session to find the problem
           statement.
 
 
 
 
More on ORA error
Jose Fco. Cleto, June      25, 2002 - 3:02 pm UTC
 
 
I also saw this error once, one of my developers was trying to insert a record and have a before insert/update tirgger with a :OLD.Field1 var the is updating part.
create or replace trigger biur_t before insert or update on t for each row
begin
  ...
  if inserting then
    ...
     :OLD.Field1 := sysdate;
  else
    ...
end;
Guess what??? it looks just normal and compile as well but every time they try to insert a record the same messages POP.
We search the web, we look some books and open the traces files and every log and trying to find every string with the offending table or user and That's all folks, we fix it and it's gone away. 
 
 
More on ORA error
Jose Fco. Cleto, June      25, 2002 - 3:03 pm UTC
 
 
I also saw this error once, one of my developers was trying to insert a record and have a before insert/update tirgger with a :OLD.Field1 var the is updating part.
create or replace trigger biur_t before insert or update on t for each row
begin
  ...
  if inserting then
    ...
     :OLD.Field1 := sysdate;
  else
    ...
end;
Guess what??? it looks just normal and compile as well but every time they try to insert a record the same messages POP.
We search the web, we look some books and open the traces files and every log and trying to find every string with the offending table or user and That's all folks, we fix it and it's gone away. 
 
 
Determine who submitted the bad SQL?
Eric Raskin, August    21, 2002 - 9:14 pm UTC
 
 
I've run your script on my database and found a few statements that are candidates for bind variables.  We have a bunch of Oracle Forms applications running, so I'm not sure which one is executing each statement.  How do I determine who submitted the offending SQL? 
 
August    22, 2002 - 8:53 am UTC 
 
Well, the shared pool by its very definition is "application agnostic" - it is after all the "shared pool"
It could be that EVERY application issues the offending sql.
It could be that 15 applications do
Or just one.
If you have the FMT files (text files representing the forms) you could "grep" them looking for references to the tables in question.
If you see the sql running (using showsql.sql available on this site via search for example), you'll be able to see who is doing it. 
 
 
 
OEM Is not using Bind variables.
A reader, August    22, 2002 - 4:56 pm UTC
 
 
Hi Tom,
Your remove_constants logic is very useful for me.
I was testing your remove_constants function in one of our devlopment environments and found one Intresting point.
/* ORACLEOEM */ SELECT MIN_VALUE, MAX_VALUE, INCREMENT_BY, LAST_NUMBER, CYCLE_FL
AG, ORDER_FLAG, CACHE_SIZE FROM SYS.DBA_SEQUENCES WHERE SEQUENCE_OWNER = ('#') A
ND SEQUENCE_NAME = ('#')
SQL_TEXT_WO_CONSTANTS
--------------------------------------------------------------------------------
  COUNT(*)
----------
       113
/* ORACLEOEM */ SELECT TEXT FROM DBA_SOURCE WHERE OWNER = '#' AND NAME = '#' AND
 TYPE = '#' ORDER BY LINE
       567
/* ORACLEOEM */ SELECT INITCAP(STATUS) FROM DBA_OBJECTS WHERE OWNER = '#' AND OB
JECT_NAME = '#' AND OBJECT_TYPE = '#'
       590
So OEM is not using your rule of thumb(it is not using bind variables). 
My doubt is why can't OEM use bind variables?
 
 
August    22, 2002 - 10:46 pm UTC 
 
can't is the wrong word.
didn't is the correct word.
It would be an OEM bug.  In fact, #1504636 is filed about this issue.  Not everyone has read my book yet ;)  Working on that.... 
 
 
 
Outstanding tuning tool!
Jimko, August    22, 2002 - 5:35 pm UTC
 
 
Using this great technique, I found and fixed three minor transgressions in my code that were wasting cache space. However the vast majority of SQL that was duplicated in the cache was generated by Oracle Sales Analyzer or Oracle Discoverer. Don't you have any in-house readers, Tom? ;-)
I can understand why OSA might not be able to use bind variables because of its dynamic nature, but Discoverer builds fairly straight forward queries against static tables. Are there any techniques we can use to shield the database from abuse by query generation tools? 
By coincidence, I had read you book up through page 448 last night. I experienced some deja vu when I resumed my reading this evening on page 449 where you cover this very function. 
Your book is excellent. I don't know why more technical documentation isn't written in the 1st person. It's the natural way to communicate. 
 
August    22, 2002 - 10:49 pm UTC 
 
Actually, in a data warehouse (such as you would be using these tools) -- not using Binds is ok.  
You need binds when you are parsing X statements / second.
When are you parsing 1 statement every Y seconds, it is not nearly as important.
OLTP = mandatory binds
Mixed Used = mostly 99% binds
DW = binds if you want to (i cannot believe i said that!)
The plans for the dataware house will be better if you use constants/literals in general.  You do not have the scalability wall since you are doing queries that take a long time (and hence you are not parsing x queries per second, the latching doesn't hit you).  Also, the usage of the shared pool is "gentler" so the space problem is not bad at all -- we have time to manage the shared pool, we aren't in a rush as much.
 
 
 
 
RE: DW = binds if you want to...
Mark A. Williams, August    23, 2002 - 1:58 pm UTC
 
 
DW = binds if you want to (i cannot believe i said that!)
Are you sure you don't have a fever?  Body snatched?  Did it feel weird to say it?
Just kidding, of course...
- Mark 
 
 
Bind Variables
vinodhps, June      02, 2003 - 12:36 pm UTC
 
 
Hi Tom ,
Function was pretty useful.. i corrected those queires which was found ........
oiisdba@OIIS8.WORLD> update t1 set sql_text_wo_constants = remove_constants(sql_text);
12867 rows updated.
oiisdba@OIIS8.WORLD> select sql_text_wo_constants, count(*)
  2    from t1
  3   group by sql_text_wo_constants
  4  having count(*) > 100
  5   order by 2
  6  /
SQL_TEXT_WO_CONSTANTS
--------------------------------------------------------------------------------------------------
  COUNT(*)
----------
SELECT * FROM T_FAS_SALE_AWA WHERE DOC_NO=@
       115
SELECT ROWID,REAM_ID,PALLET_CODE,BATCH_NO,PART_KEY,QLTY_DEST,USERID,DATESTAMP,PRINT_CNT,RG_VARIETY
D,SMR_FLAG,REAM_STATUS,DEFECT_CD,REAM_WT FROM T_PMS_REAM_DTL WHERE PART_KEY = @ AND REAM_ID > '#' 
D REAM_ID < '#' AND (PALLET_CODE=:@) AND (BATCH_NO=:@) ORDER BY REAM_ID
       489
Thanks... 
 
 
Very useful
A reader, June      05, 2003 - 4:37 pm UTC
 
 
  
 
how can pl/sql code lead to lack of usage of bind variables 
A reader, June      10, 2003 - 1:48 pm UTC
 
 
"anywhere there is a PLSQL variable -- it is really a host variable, a bind 
variable.  That is part of the beauty of PLSQL -- it makes binding almost MOOT.  
You have to absolutely go out of your way to NOT bind in plsql.
"
well, if you do a simple select as below in pl/sql
wont it violate the always-use-bind-variable rule
(due to the hard coded constant 'FGL'?
....
select a
into b
from t
where t.x = 'FGL';
....
Thanx!
 
 
June      10, 2003 - 1:52 pm UTC 
 
that is properly bound.
Tell me -- if you run that procedure over and over and over -- how many different SQL statements will you have?  
One.
If on the other hand, you code:
   open ref_cursor for 'select * from t where t.x = ' || some_variable;
the answer to that question will be:
infinitely many.
That is why you need to use binds in dynammic sql:
  open ref_cursor for 'select * from t where t.x = :x' USING some_variable;
but in static sql in plsql -- you need not.  By definition, in static sql, the values will NEVER change and you need bind only when the values CHANGE 
 
 
 
thanx for a clear explanation!
A reader, June      10, 2003 - 2:46 pm UTC
 
 
now I understand - in pl/sql if static sql then anyways
the query does not change -
if not then you have to use variables which are
bound - so is there anyway that you could be violating
the "always-bind" rule in pl/sql?
Thanx! 
 
 
oops! got it!
A reader, June      10, 2003 - 2:48 pm UTC
 
 
i guess using the dynamic sql you showed is the
way you would violate the "always-gind" rule..'thanx!:) 
 
 
static sql in pl/sql
A reader, June      10, 2003 - 3:44 pm UTC
 
 
Tom
You said,
" but in static sql in plsql -- you need not.  By definition, in static sql, the 
values will NEVER change and you need bind only when the values CHANGE ".
Does this argue for encapsulating all select statements in functions (That could be reused later?)  this would ensure that there are no two select stmts that are the same with different values within pl/sql packages?
e.g.
instead of having 
select x
from w 
where v = ‘F’
at one place 
and 
select x from w where v = ‘G’
at another you make a function of that select statement and use it.
Do you see any pros/cons of this approach?
Thanx for your wonderful site!:)
 
 
June      10, 2003 - 7:57 pm UTC 
 
that would be taking it to an extreme perhaps.  not that I'm 100% down on it -- i just see it heading towards "no sql in your plsql package, you have to add it to this package over here" sort of runs.  A  good idea taken too far can become an inhibitor.
Given that it is humans typing in the code, the probability that we'll flood the shared pool with hundreds of statements that *could have been shared* is limited.
So, no, I would not encapsulate all sql in functions.
If I could just get everyone to put all sql in plsql.... that would be a huge step forward 
 
 
 
thanx - that makes sense!
A reader, June      10, 2003 - 8:03 pm UTC
 
 
  
 
bind variables in install statements
A reader, June      11, 2003 - 4:06 pm UTC
 
 
lot of times some data has to be there in the
installed tables - usually metadata...
in our case, those dont use bind values.
For exmaple,
insert into table t1 values ( 1, 'metadata 1');
insert into table t1 values ( 2, 'metadata 1');
insert into table t1 values ( 3, 'metadata 1');
There could be many such statements.
Since they are one time they do fill up the library
cache once in the beginning.
Do you think they are harmful (Since their effect
is only in the beginning) 
 
June      12, 2003 - 8:19 am UTC 
 
if it would be as easy to avoid as not avoid, you should avoid it.  
what would be wrong with a file like:
1,'metadata 1'
2,'metadata 2'
....
and sqlldr or an external table (in 9i)... 
 
 
 
thanx!
A reader, June      12, 2003 - 11:27 am UTC
 
 
I guess i just wanted to gauge the priority of this work - 
from what you say, it seems like it should be done but
is not such a big problem
Regards
 
 
 
A reader, June      24, 2003 - 5:05 pm UTC
 
 
Tom,
I used your function remove_constants and have found out that are whole buch of queries that dont use bind variables.
The situation is I dont have acces to the codes so i cannot fix it (3rd party software) and to make matters worse we are running on 8.0.5. To upgarde the systems to 9i will take atleast 3-4 months.Till then can you suggest something that i can do.
Thanks.
 
 
June      25, 2003 - 11:36 am UTC 
 
ask they 3rd party vendor why they write such bad code and when are they going to fix it?
if you cannot fix the code, which has a bug, there is not much you can do in 8.0.
in 8i and up you MIGHT be able to use cursor_sharing, MAYBE. 
 
 
 
Fan Zhang, July      12, 2003 - 2:34 am UTC
 
 
Tom,
 As the function remove_constants converts all the numbers to @, it may also change the names of columns and tables.  e.g., both 'select c1 from t1' and 'select c2 from t2' will be converted as 'SELECT C@ FROM T@'. Is it better to conver only the numbers after the '=' sign?  Thanks, 
 
July      12, 2003 - 9:35 am UTC 
 
no, it is better to not over complicate things.
This is a simple solution to a nasty problem.  I assume a sensible human being will be reading the output and upon seeing 
select c@ from t@
in the report they would know full well "ok, ignore that one"
I would not want to write a SQL parser -- it is not just = what about:
select substr( x, 1, 40 ) from t;
select substr( x, 1, 41 ) from t;
select substr( x, 33, 20 ) from t;
select 55, a.* from a;
select 56, a.* from a;
select * from t where x > 55;
select * from t where x > 56;
select * from t where x between 1 and 100;
select * form t where x between 32 and 52;
and so on..... 
 
 
 
Fan Zhang, July      13, 2003 - 12:56 am UTC
 
 
Tom,
Thanks very much for your reply.  I agree the situation is much more complicated than I first thought, and its hard to list all the possibilities where numbers are used as values. On the other hand, the numbers is used in a name (tables, columns, schemas
) in limited number of ways.  By taking this advantage, the following modified function seems working in most cases, though I feel there can be many exceptions (e.g., to_date).  
The reason for me to pursue the issue is that I know in some databases, for security raeson, numbers are used intensively in column/table names.  If we get 1000 'select * from t@ where c@ = @', it may come from 1 case of 'select * from t1 where c1=@' and 999 of 'select * from t2 where c2=@'.  
*****************
create or replace function 
remove_constants( p_query in varchar2 )  return varchar2
as
    l_query         long;
    l_char          varchar2(1);
    l_in_quotes     boolean default FALSE;
    l_before_number     boolean default FALSE;
    l_ascii         number;
begin
    for i in 1 .. length( p_query )
    loop
        l_char  := substr(p_query,i,1);
        l_ascii :=ascii(l_char);
        if ( l_in_quotes  ) 
        then
            if (l_char ='''') 
            then
               l_query     := l_query || '''';
               l_in_quotes := FALSE;
            else
               l_query     := l_query || '#';
            end if;
        elsif ( NOT l_in_quotes and l_char = '''' )
        then
            l_in_quotes    := TRUE;
            l_query        := l_query || '''';
        elsif ( (NOT l_in_quotes ) 
                and l_before_number
                and (l_ascii between 48 and 57))
        then
            l_query := l_query || '@';
        else
            l_query := l_query || l_char;
        end if;
        if ( l_ascii = 36                    -- 36     => $
              or l_ascii = 95                -- 95     => _
              or l_ascii between 65 and 90   -- 65-90  => A-Z
              or l_ascii between 97 and 122  -- 97-122 => a-z
           ) 
        then
            l_before_number := FALSE;
        elsif (not l_before_number
               and l_ascii between 48 and 57 -- 48-57  => 0-9
              )
        then
            l_before_number := FALSE;
        elsif ( NOT l_in_quotes  )
        then
            l_before_number := TRUE;
        end if;
    
    end loop;
    for i in 0 .. 8 loop
        l_query := replace( l_query, lpad('@',10-i,'@'), '@' );
        l_query := replace( l_query, lpad(' ',10-i,' '), ' ' );
        l_query := replace( l_query, lpad('#',10-i,'#'), '#' );
    end loop;
    dbms_output.put_line(l_query);
    return upper(l_query);
    
end;
/
************ 
 
July      13, 2003 - 9:38 am UTC 
 
this sentence:
for security raeson, numbers are used intensively in column/table names.
should read:
in a misguided attempt to achieve security via obscurity, numbers are used intensively in column/table names achieving no actual security benefit but removing much value from the database itself.
 
 
 
 
Which Process?
Sunil Gururaj, July      15, 2003 - 8:36 am UTC
 
 
Hi Tom,
Could you let me know which "ADDRESS" column of v$session relates to the address in v$sqlarea view on which your above query is operating on.
Put it simply, I need to find out the program or the process which is NOT using Binds and need to advice the development team accordingly.
Thanks, 
 
July      15, 2003 - 10:06 am UTC 
 
and you cannot tell by the queries?
sql_address column is probably what you are looking for -- to goto v$sql 
 
 
 
Nice Tool to catch the culprit SQLs
SUDIPT SINHA, August    30, 2003 - 7:57 am UTC
 
 
Hi Tom
It is very nice tool to catch the culprit SQLs. Here Iam using Oracle JDeveloper. I have query like this 
SELECT XYZ.TADIBANK_ID, XYZ.TADIBRANCH_ID, XYZ.TADVCHALLAN_ID, XYZ.TADDCHALLAN_DATE, XYZ.CTDILOGIN_ID, XYZ.CTDDMODIFIED_DATE, XYZ.CTDIOFFICE_ID, XYZ.TADVREGN_ID, XYZ.TADVCST_REGN_ID, XYZ.TADICIRCLE_OFFICE_ID, XYZ.TADIASSMT_YEAR, XYZ.TADVACT_ID, XYZ.TADIPERIOD, XYZ.TADRCHALLAN_AMT, XYZ.TADVSCROLL_ID, XYZ.TADVERROR_ID, XYZ.TADVRECONCILIATION_FLAG, XYZ.TADIRECONCILIATION_COUNT, XYZ.TADVREC_CONFIRM_FLAG_PCR_RCPT, FUNC1('#',XYZ.TADVACT_ID,'#') AS ACT, XYZ.TADDFROM_DATE, XYZ.TADDTO_DATE, FUNC1('#','# .........................
FROM XYZ 
WHERE...............
in where clause I have used the bind variable. But in the FUNC1 I have used the literals and it should be same for all the users, still it is coming in that query(which u have given) for more than 100 times. Whether I have to use bind for those literal also?
Regards
Sudipt 
 
August    30, 2003 - 10:54 am UTC 
 
are the literal values for the queries the SAME?
what release of the database are you using?
are the queries executed from a stored procedure or directly? 
 
 
 
Nice Tool to catch the culprit SQLs.. contd..
SUDIPT SINHA, September 01, 2003 - 12:47 am UTC
 
 
1. The literal values for the queries are the SAME (for all users)
2. Release of the database -- Oracle 9.2.0.3
3. The queries are executed directly using JDBC( in built in Oracle JDeveloper). FUNC1() is a stored function in Oracle DB.  
 
 
September 01, 2003 - 8:29 am UTC 
 
peek into v$sql_shared_cursor for that query and see which columns are flagged with "Y"s -- eg, this is a short excerpt from my book "Efficient Oracle by design" showing what I mean:
...
We simply set up the four users A, B, C, and D. We grant CREATE SESSION and CREATE TABLE privileges to users A, B, and D, and grant just CREATE SESSION to C. Then we run the following script:
create public synonym emp for d.emp;
alter system flush shared_pool;
connect a/a
create table emp ( x int );
select * from emp;
connect b/b
create table emp ( x int );
select * from emp;
connect d/d
create table emp ( x int );
grant select on emp to c;
select * from emp;
connect c/c
select * from emp;
Now, let's take a quick peek at V$SQL, which shows all of the currently cached SQL statements.
ops$tkyte@ORA920> select address, executions, sql_text
  2    from v$sql
  3   where upper(sql_text) like 'SELECT * FROM EMP%';
ADDRESS  EXECUTIONS SQL_TEXT
-------- ---------- ------------------------------
58DBD9CC          1 select * from emp
58DBD9CC          1 select * from emp
58DBD9CC          2 select * from emp
We can see that there are three versions of the query in the shared pool and that one of the versions was used two times-that is the query submitted by users C and D. 
We can also query V$SQL_SHARED_CURSOR to determine exactly why Oracle developed three query plans, to discover the root cause for the mismatch here. This view has many columns that can be used to determine why a plan in the shared pool was not shared. For example, the ROW_LEVEL_SEC_MISMATCH column would be flagged for two queries that appear to be the same but differed at runtime based on the security predicate returned by Oracle's Virtual Private Database (VPD) feature. The OUTLINE_MISMATCH column would be flagged if one query used a query outline and the other did not. Other columns in this view provide similar mismatch information. In this example, we can see this information regarding our queries:
ops$tkyte@ORA920> select kglhdpar, address,
  2         auth_check_mismatch, translation_mismatch
  3    from v$sql_shared_cursor
  4   where kglhdpar in
  5   ( select address
  6       from v$sql
  7      where upper(sql_text) like 'SELECT * FROM EMP%' )
  8  /
KGLHDPAR ADDRESS  AUTH_CHECK_MISMATCH TRANSLATION_MISMATCH
-------- -------- ------------------- --------------------
58DBD9CC 59D4C9C8 N                   N
58DBD9CC 59E54EB0 Y                   Y
58DBD9CC 5898D42C Y                   Y
In this case, Oracle flagged two columns: AUTH_CHECK_MISMATCH, meaning the authorization/translation check failed for the existing cursor (query plan), and TRANSLATION_MISMATCH, meaning the base objects of the child cursor (query plan) do not match. This shows us exactly why there are three queries plans (child cursors): The base objects referenced were different. 
 
 
 
 
 
Nice Tool to catch the culprit SQLs.. contd..  
SUDIPT SINHA, September 02, 2003 - 9:15 am UTC
 
 
I am sorry that the user I am talking about are the browing user not the Database user.
In my database I am using only one schema(one DB user). The application is accessed through Oracle 9iAS. Still I am getting so many count using your query.
Regards
Sudipt 
 
September 02, 2003 - 10:39 am UTC 
 
use the technique above to find out WHY 
 
 
 
Library Latch Cache Contention
JHT, October   30, 2003 - 1:31 pm UTC
 
 
Tom,
Wow, I think this is the best website for interesting and complicated oracle issues!!!
If I am reading my statspack report correctly, I have a library latch cache contention.  So I ran the "remove_constants" procedure Tom recommended at the top of this thread and no SQL with > 100 counts turned up.  I have set cursor_sharing=FORCE in the 8.1.6 db.  What are other possible reasons for library cache latch contention?  Below are snippets from the statspack report...  Thanks.
                                                                Snap Length
Start Id    End Id       Start Time             End Time         (Minutes)
--------  --------  --------------------  --------------------  -----------
     190       191  26-Oct-03 01:07:56    26-Oct-03 01:16:00           8.07
Cache Sizes
~~~~~~~~~~~
           db_block_buffers:      131072
              db_block_size:        8192
                 log_buffer:      524288
           shared_pool_size:   100000000
Load Profile
~~~~~~~~~~~~
                                       Per Second      Per Transaction
                                  ---------------      ---------------
                  Redo size:           151,257.45             2,187.62
              Logical reads:             6,142.08                88.83
              Block changes:               946.70                13.69
             Physical reads:               778.34                11.26
            Physical writes:                77.79                 1.13
                 User calls:             1,609.01                23.27
                     Parses:             1,047.90                15.16
                Hard parses:                 0.01                 0.00
                      Sorts:                 1.05                 0.02
               Transactions:                69.14
              Rows per Sort:      117.75
  Pct Blocks changed / Read:       15.41
         Recursive Call Pct:       60.36
 Rollback / transaction Pct:        0.30
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Buffer Nowait Ratio:       99.94
        Buffer  Hit   Ratio:       87.33
        Library Hit   Ratio:      100.04
        Redo   NoWait Ratio:      100.00
       In-memory Sort Ratio:       97.84
           Soft Parse Ratio:      100.00
            Latch Hit Ratio:       89.24
Top 5 Wait Events
~~~~~~~~~~~~~~~~~                                             Wait     % Total
Event                                               Waits  Time (cs)   Wt Time
-------------------------------------------- ------------ ------------ -------
latch free                                      2,182,681      251,374   42.78
slave wait                                         30,702      137,440   23.39
db file sequential read                           127,626       74,321   12.65
log file sync                                      43,839       41,690    7.09
io done                                            30,386       40,844    6.95
         -------------------------------------------------------------
                                                Pct    Avg                Pct
                                    Get         Get Sleeps      Nowait Nowait
Latch Name                        Requests     Miss  /Miss    Requests   Miss
------------------------------- ------------ ------ ------ ----------- ------
Active checkpoint queue latch            924    0.0                  0
Checkpoint queue latch               121,876    0.0    0.1           0
Token Manager                            164    0.0                  0
archive control                            2    0.0                  0
archive process latch                      2    0.0                  0
cache buffer handles                     138    0.0                  0
cache buffers chains               5,518,468    0.2    0.1     666,964    0.0
cache buffers lru chain              475,650    0.2    0.0     382,391    0.2
channel handle pool latch                170    0.0                170    0.0
channel operations parent latch          340    0.0                170    0.0
constraint object allocation             243    0.0                  0
direct msg latch                      93,078    0.0    0.0           0
dml lock allocation                  247,685    0.1    0.0           0
done queue latch                      29,564    0.0             29,567    0.0
enqueue hash chains                  330,628    0.2    0.1           0
enqueues                             394,860    0.2    0.1           0
event group latch                        170    0.0                  0
global transaction                     7,431    0.0                  0
global tx free list                      531    0.0                  0
global tx hash mapping                 2,090    0.0                  0
job_queue_processes parameter l          154    0.0                  0
ksfv messages                        122,630    0.0                  0
ktm global data                            2    0.0                  0
latch wait list                    1,409,267    2.1    0.1   1,653,622    4.0
library cache                     11,937,161   22.3    0.8           0
library cache load lock                   56    0.0                  0
list of block allocation              71,525    0.0    0.0           0
 
 
October   30, 2003 - 9:54 pm UTC 
 
confusion
you ran for 8 minutes (8*60 = 480 cpu seconds)
but you had 2,513 seconds of waits..
are you like a 16/32 cpu machine here?
you do not have a hard parse issue - you have 100% soft parses (PERFECTION, congrats!)
what you might have is an "over parse" issue, soft parses are less expensive than hard, but only "no parse" is free.
details. need more details -- describe the system 
 
 
 
Ratio query x parse
Marcio, October   31, 2003 - 8:55 am UTC
 
 
Tom, I'm wondering about you said:
"You need binds when you are parsing X statements / second.
When are you parsing 1 statement every Y seconds, it is not nearly as important."
How can I get such ratio? -- x statements / second.
thanks,
Marcio
 
 
November  01, 2003 - 11:40 am UTC 
 
you would sort of know -- it is your system, are you OLTP with "transactions per second" or are you a warehouse with N concurrently executing massive queries.
But, you can use statspack to see executions/second and transactions/second to get a gist. 
 
 
 
Library Latch Cache Contention
JHT, November  03, 2003 - 9:11 am UTC
 
 
Thanks Tom for your earlier response to this issue.  
Our DB Server is 8 CPUs.  It is an OLTP system where the majority of the processing is this:  There is A LOT (26,000 per second) of inserts into a view.  An "instead of" trigger fires (and discards about 23,000 inserts because of some application logic).  The rest (3,000 inserts) is processed and updates/deletes/inserts into a table (IPMAP) that keeps track of what cable modem owns what ip address.  This triggers also inserts into a "history" table to store this same information.  
If this is a soft parse issue, how do I go about improving this?
Below is the costly SQL statements (in terms of buffer gets) in this 8 minute window.  The first statement is the insert into the VIEW.
   Buffer Gets     Executes   per Exec    Total   Hash Value
-------------- ------------ ------------ ------ ------------
SQL statement
------------------------------------------------------------------------------
     1,848,346      214,866          8.6   62.2   2948872974
insert into LEASEVIEW (IPADDR,REGIONID,DEVICEID,RAREMOTEID,DEVICETYPE,LEASEDAT
       859,372      214,946          4.0   28.9    837720088
SELECT COUNT(*)   FROM IPMAP  WHERE IPADDR = :b1  AND REGIONID = :b2  AND DEVI
       216,003       27,029          8.0    7.3   1919955916
SELECT COUNT(*)   FROM IPMAP  WHERE ((IPADDR = :b1  AND REGIONID = :b2 ) OR (D
       205,496       27,019          7.6    6.9    146615416
UPDATE IPMAP SET DEVICEID=:b1,RAREMOTEID=:b2,DEVICETYPE=:b3,LEASEDATE=:b4,EXPD
       198,669       27,040          7.3    6.7   1492083554
SELECT AD.ACCTTYPE,DA.DATAACCOUNTID ACCOUNTID   FROM ACCTDEVICE AD,DATAACCOUNT
 
 
November  03, 2003 - 2:42 pm UTC 
 
I would not have done it that way -- for such intensive processing -- I would have built a stored procedure that would reject 23 out of 26k records -- inserting the other 3k.
what is the calling application and is it parsing the insert before each and every insert?
also -- the trigger, does it contain the code "in it" or is the trigger a single line -- a call to a stored procedure.  If not, each execute is going to cause a soft parse of all of the trigger SQL.  Consider:
ops$tkyte@ORA920PC> create table t ( x int );
 
Table created.
 
ops$tkyte@ORA920PC> create or replace view v as select * from t;
 
View created.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> create or replace procedure p
  2  as
  3  begin
  4          for x in ( select * from dual IN_PROCEDURE )
  5          loop
  6                  null;
  7          end loop;
  8  end;
  9  /
 
Procedure created.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> create or replace trigger v_trigger
  2  instead of insert on v
  3  begin
  4          for x in ( select * from dual IN_TRIGGER )
  5          loop
  6                  null;
  7          end loop;
  8          p;
  9  end;
 10  /
 
Trigger created.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> alter session set sql_trace=true;
 
Session altered.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> insert into v values ( 1 );
 
1 row created.
 
ops$tkyte@ORA920PC> insert into v values ( 1 );
 
1 row created.
 
ops$tkyte@ORA920PC> insert into v values ( 1 );
 
1 row created.
 
ops$tkyte@ORA920PC> insert into v values ( 1 );
 
1 row created.
 
ops$tkyte@ORA920PC> insert into v values ( 1 );
 
1 row created.
 
ops$tkyte@ORA920PC>
tkprof shows us:
select * from dual IN_TRIGGER
                                                                                                  
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        5      0.00       0.00          0          0          0           0
Execute      5      0.00       0.00          0          0          0           0
Fetch       10      0.00       0.00          0         15          0           5
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       20      0.00       0.00          0         15          0           5
********************************************************************************
select * from dual IN_PROCEDURE
                                                                                                  
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      5      0.00       0.00          0          0          0           0
Fetch       10      0.00       0.00          0         15          0           5
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       16      0.00       0.00          0         15          0           5
                                                                                                  
See how the trigger sql was parsed 5 times for 5 executes, but plsql stored procedures nicely "cache" the sql.
So, my advice:
a) don't use the view
b) use a stored procedure
c) make DARN sure the caller parses the begin p(....); end; block ONCE and executes it over and over and over again.
your parsing will go way way way down.
 
 
 
 
 
Library Latch Cache Contention
JHT, November  03, 2003 - 10:32 am UTC
 
 
Oops...I meant 26,000 inserts per minute (not per second) 
 
 
Pauline, January   15, 2004 - 5:19 pm UTC
 
 
Tom,
When I use the way you provided to us to find the statements
not using BIND variable, I see something in our production database like:
SQL_TEXT_WO_CONSTANTS
--------------------------------------------------------------------------------
  COUNT(*)
----------
SELECT DISTINCT ADDRESS_TO_PTY_ID FROM PARTY_ACCOUNT_ADDRESSES PAA WHERE PAA.ACCT_ID =@ AND PAA.PTY_ID = ( SELECT PTY_ID FROM PARTY_ACCOUNTS PTYA, PRIMARY_ACCOUNTS PRIMA WHERE PTYA.ACCT_ID =@ AND PTYA.ACCT_ID = PRIMA.ACCT_ID AND PTYA.PTYACCTROLE_ID = @ AND NVL(PTYA.DELETED_FLG,'#') <> '#' AND ROWNUM < @ GROUP BY PTYA.PTY_ID ) AND NVL(DELETED_FLG,'#') <> '#' AND PAA.ADDRESS_ID = @ AND PAA.ACCTADDR_USETYP_ID = @
       292
Then I try to do:
select sql_text from v$sql 
where upper(sql_text) like 'SELECT DISTINCT ADDRESS_TO_PTY_ID FROM PARTY_ACCOUNT_ADDRESSES PAA WHERE PAA.ACCT_ID%';
I see no rows selected. 
If I do :
select sql_text from v$sql 
where upper(sql_text) like 'SELECT DISTINCT ADDRESS_TO_PTY_ID%';
Then I see 292 rows selected.
Why that upper(sql_text) not working for the longer string?
Is there any limitation for using upper function?
Thanks.
  
 
January   16, 2004 - 1:06 am UTC 
 
you must have the white space or something wrong in your like string (maybe a tab or newline hiding in there that you are not seeing)
like works dandy with long strings.  no problems there -- you just need the right input. 
 
 
 
Views
Marcio, January   16, 2004 - 6:43 am UTC
 
 
<quote>
So, my advice:
a) don't use the view
b) use a stored procedure
c) make DARN sure the caller parses the begin p(....); end; block ONCE and 
executes it over and over and over again.
</quote>
About a) In this context -- why do I not use views?
 
 
January   16, 2004 - 11:19 am UTC 
 
well, i thought I showed why
the instead of trigger parses the sql for each triggering statement.
the procedure does not. 
 
 
 
Views for maintenance.
Marcio, January   16, 2004 - 2:54 pm UTC
 
 
Sorry, I was talking about VIEWs, because I use it
to manage insted of TABLES directly -- I keep tables under my own control
and give grants on views... more or less like this:
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> create sequence s;
Sequence created.
ops$t_mp00@MRP920> create table p$ ( id int primary key,
  2                    name  varchar2(10),
  3                    qty_c int default 0 );
Table created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> create or replace trigger p$_bifer
  2  before insert on p$ for each row
  3  begin
  4          select s.nextval into :new.id from dual;
  5  end;
  6  /
Trigger created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> create or replace view p
  2  as
  3    select id p_id, name, qty_c q from p$;
View created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> create table c$ ( id int primary key, name varchar2(10), p_id references p$ );
Table created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> create or replace trigger c$_bifer
  2  before insert on c$ for each row
  3  begin
  4          select s.nextval into :new.id from dual;
  5          add_p(:new.p_id);
  6  end;
  7  /
Warning: Trigger created with compilation errors.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> create or replace view c
  2  as
  3    select id c_id, p_id, name child_name from c$
  4  /
View created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> create or replace procedure add_p ( i in number )
  2  as
  3  begin
  4          update p
  5             set q = q + 1
  6           where p_id = i;
  7  end;
  8  /
Procedure created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> show error
No errors.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> insert into p(name) values ( 'Marcio');
1 row created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> insert into c(p_id, child_name) values (1, 'Alicia');
1 row created.
ops$t_mp00@MRP920> insert into c(p_id, child_name) values (1, 'Jack');
1 row created.
ops$t_mp00@MRP920> insert into c(p_id, child_name) values (1, 'Nicole');
1 row created.
ops$t_mp00@MRP920>
ops$t_mp00@MRP920> select * from p;
      P_ID NAME                Q
---------- ---------- ----------
         1 Marcio              3
1 row selected.
ops$t_mp00@MRP920> select * from c;
      C_ID       P_ID CHILD_NAME
---------- ---------- ----------
         2          1 Alicia
         3          1 Jack
         4          1 Nicole
3 rows selected.
ops$t_mp00@MRP920> select * from p$;
        ID NAME            QTY_C
---------- ---------- ----------
         1 Marcio              3
1 row selected.
I use this to maybe rename column, change order of columns, whatever... up until now thought this is good way to manage schemas. What do you think?
thanks,
 
 
January   17, 2004 - 1:12 am UTC 
 
if you are talking about views in general -- I've said over and over "views are good"
if you are talking about "should my answer to which you referred be changed to say use the view instead of procedure" -- no, in this case not. 
views are not 100% evil
views are not 100% good
views are a tool
and in this case (the case I was answering above) not the right choice IMO.
 
 
 
 
My mistake 
Marcio, January   17, 2004 - 1:29 pm UTC
 
 
Sorry my misunderstood, when I saw your comment about views, I just forgot context and put my follow up. 
I work for that way (demonstrated above) following your advice found here on this site (about views).
Thanks. 
 
 
TRS, March     18, 2004 - 4:47 pm UTC
 
 
This was almost as good as the Thia soup they've named after you....  ;) 
 
 
Oracle Text and bind variable
Angel, June      04, 2004 - 1:00 pm UTC
 
 
Hi Tom,
This is a very useful tool for catching the not-binded sqls.
One thing that puzzles me is that always when we run this, it turns out that the biggest offenders are internal sqls of Oracle Text.
Could you tell me if there are any legitimate reasons why Oracle Text is not using binded parameters?
Thanks.
DECLARE SEL NUMBER; BEGIN :@ := "CTXSYS"."TEXTOPTSTATS".ODCISTATSSELECTIVITY( S
YS.ODCIPREDINFO('#', '#', '#', @), SEL, SYS.ODCIARGDESCLIST(SYS.ODCIARGDESC(@, N
SQL_TEXT_WO_CONSTANTS
--------------------------------------------------------------------------------
  COUNT(*)
----------
ULL, NULL, NULL, NULL, NULL), SYS.ODCIARGDESC(@, NULL, NULL, NULL, NULL, NULL),
SYS.ODCIARGDESC(@, '#', '#', '#', NULL, NULL), SYS.ODCIARGDESC(@, NULL, NULL, NU
LL, NULL, NULL)), @, NULL , NULL, '#', SYS.ODCIENV(@, @)); IF SEL IS NULL THEN :
@ := -@; ELSE :@ := SEL; END IF; EXCEPTION WHEN OTHERS THEN RAISE; END;
       725
 DECLARE COST SYS.ODCICOST := SYS.ODCICOST(NULL, NULL, NULL, NULL); BEGIN :@ :=
"CTXSYS"."TEXTOPTSTATS".ODCISTATSINDEXCOST( SYS.ODCIINDEXINFO('#', '#', SYS.ODCI
COLINFOLIST(SYS.ODCICOLINFO('#', '#', '#', '#', NULL, NULL)), NULL, @, @), @.@,
SQL_TEXT_WO_CONSTANTS
--------------------------------------------------------------------------------
  COUNT(*)
----------
COST, SYS.ODCIQUERYINFO(@, SYS.ODCIOBJECTLIST(SYS.ODCIOBJECT('#', '#'))), SYS.OD
CIPREDINFO('#', '#', NULL, @), SYS.ODCIARGDESCLIST(SYS.ODCIARGDESC(@, NULL, NULL
, NULL, NULL, NULL), SYS.ODCIARGDESC(@, NULL, NULL, NULL, NULL, NULL), SYS.ODCIA
RGDESC(@, '#
       816
 
 
June      04, 2004 - 1:33 pm UTC 
 
which release is that -- i know they fixed that.....
Not happening in my database (and i use text heavily) 
 
 
 
Oracle Text and bind variable  
Angel, June      07, 2004 - 5:37 am UTC
 
 
Hi Tom,
It's Oracle9i Release 9.2.0.3.0 for Windows.
I went to   
</code>  
http://otn.oracle.com/software/products/oracle9i/index.html  <code>
to check what was the latest release of 9i and I found that 9.2.0.3 is not available to download (9.2.0.2 is the latest for Windows)
This is strange, because I am sure it was there before. Do you know why it has been removed?
Please tell me if there is something I got wrong. Thanks,  
 
Latch contention algorithm
A reader, June      23, 2004 - 12:13 pm UTC
 
 
Tom,
I reviewed your book (Expert One-on-One Oracle and Oracle Perf. By design, Cary Millsap's Optimizing Oracle Performance. Based on these, I have come up with a little logic of how the Oracle kernel's latch acquisition algorithm will look like at a very high level. Please confirm if my understanding is correct. The code snippet is shown below :
Code snippet for latch that sorround an Oracle kernel code
==========================================================   
if  get_latch(latch_name,Mode) {
    /*
        .....
        .....
        Oracle kernel code associated for the latch
        .....
        .....
   */
    release (latch_name)
}
Latch acquisition algorithm
===========================
Boolean get_latch (char *latch_name, char Mode) {
        Latch_Acquired := 0;
         If  (latch for 'latch_name' available) {
              Latch_Acquired := 1;      /* Mark latch as acquired */
        }
        If  (Latch_Acquired) {
            If (Mode = 'I') {
                Increment Gets count for Immediate mode
           }
           else {
                Increment Gets count for Willing-to-Wait mode
           }
        }
        else {
             If (Mode = 'W') {
                Increment MISSES count for Willing To Wait mode
                /*
                  The while loop below consumes CPU time as the process consumes CPU doing nothing but
                  spiining for the latch
                */
                While (NOT Latch_Acquired) {
                    If ( Request_Count++ <= LATCH_SPIN_COUNT) {
                                 get_latch (latch_name,Mode);
                    }
                    sleep (x);  /* This will post a Latch Free WAIT event and causes */
                                   elapsed time exceed CPU time */
                    Request_Count = 0;
                }
              }
              else {
                 Increment MISSES count for Immediate mode
              }
        }
        return (Latch_Acquired);
}
Please confirm if my understanding is correct. 
 
June      23, 2004 - 1:21 pm UTC 
 
funny how much indentation matters ;)  I never could read the C code that used that (very common) style of {}, always had to pretty print it...
anyway, I think the spin loop you have is a bit off, but the gist is there, not going to nit-pick too much, this is how I might psuedo code that part:
       If (Mode = 'W')
       {
           Increment MISSES count for Willing To Wait mode
           /*
               The while loop below consumes CPU time as the process consumes
               CPU doing nothing but spining for the latch
           */
           While (NOT Latch_Acquired)
           {
               for( request_count = 0;
                    request_count <= spin_count && !latch_acquired;
                    request_count++ )
               {
                   try to grab the latch, recursion would be logically wrong...
               }
               if !Latch_Acquired
               {
                   sleep (x);  /* This will post a Latch Free WAIT event 
                              and causes elapsed time exceed CPU time, 
                              note that an overburdened CPU will do the
                              same in a spin loop (ela > cpu) as we get
                              pre-empted */
                   increment sleeps
               }
           }
      }
 
 
 
 
Clarification
A reader, June      23, 2004 - 2:03 pm UTC
 
 
Tom,
In the above feedback, you mentioned that recursion would be logically wrong. 
1. Can you please eloborate on this please
2. Also, when the process is pre-empted because of busy CPU, it will not show as WAIT line but will be represented by "Time spent not using the CPU" (which per Cary Millsap's response time analysis would be counted as N ==> time spent not utilizing the CPU) and will not appear in any of the wait interfaces since the wait interfaces do not show the time waiting for CPU.
Is my understanding of 2 correct?
As always, thanks for your very clear explanation 
 
June      23, 2004 - 2:47 pm UTC 
 
1) the recursion would go through all of the checks again and as latch acquired is a local variable, it would be an infinite loop
2) correct it will not be wait time, it will be unacouunted time.  elapsed time will show it, you won't be able to look at the waits and see what it was.
My point was you stated:
This will post a Latch Free WAIT event and 
causes elapsed time exceed CPU time
well, spinning can also cause "elapsed time exceed cpu time" if we get bumped off.  no wait can be recorded -- but ela will go up while CPU does not. 
 
 
 
Clarification
A reader, June      23, 2004 - 2:04 pm UTC
 
 
Tom,
In the above feedback, you mentioned that recursion would be logically wrong. 
1. Can you please eloborate on this please
2. Also, when the process is pre-empted because of busy CPU, it will not show as WAIT line but will be represented by "Time spent not using the CPU" (which per Cary Millsap's response time analysis would be counted as N ==> time spent not utilizing the CPU) and will not appear in any of the wait interfaces since the wait interfaces do not show the time waiting for CPU.
Is my understanding of 2 correct?
As always, thanks for your very clear explanation 
 
 
Remove_Constants
Neeraj, June      23, 2004 - 7:07 pm UTC
 
 
Tom,
  The remove_constants function is proving to be very 
  helpful. It can tell you right away how many copies of
  the same SQL statement are there in the SQLAREA. Is there 
  a query which can show the amount how much memory is 
  being wasted per SQL statement as compared to the total 
  memory allocated by shared_pool_size parameter..? 
Thanks Always for your response.
Neeraj
 
 
June      24, 2004 - 9:03 am UTC 
 
there are columns in v$sql ending in _MEM you can aggregate up. 
 
 
 
Library Cache Latch and Shared Pool Latch
Vivek Sharma, June      28, 2004 - 2:14 am UTC
 
 
Dear Tom,
I have a Document listed on orapub.com. The Document Titled "Conquering Oracle Latch Contention" is written by Craig A. Shallahamer. In the document on page no 12, the author states about the Library Cache Latch Contention that
"Very generally and incomplete, the library cache kernel code is used to check if a SQL Statement is cached in the library cache".
I think that the author means that the Library Cache Latch Contention occurs to check the parsed version of a SQL Statement.
As per my understanding, the author is wrong in his statement. I regularly read your articles and visit this site and based on this I have understood that
Library Cache Latch contention can occur if there are too many parses in the Library Cache probably due to any of these reasons 
1. Not using Bind variables
2. Shared Pool is too small
etc.
whereas Shared Pool Latch is used for the purpose what the author of above said article states for Library Cache Latch. i.e. Shared Pool Latch is used to scan the Shared Pool (library Cache) to check if a SQL Statement is cached in the library cache. In this case, if the sql is found, then the parsing is avoided whereas if the statement is not in the Library cache then the library cache latch is acquired to parse the Statement. Am I correct ?
Regards
Vivek
 
 
June      28, 2004 - 8:20 am UTC 
 
the shared pool latch is used to protect memory allocations the library cache is used to protect modifications to these structures after allocation.
it would be the library cache latch that gets hit on the parse. 
 
 
 
Library Cache Latch v/s. Shared Pool Latch
Vivek Sharma, June      29, 2004 - 1:00 am UTC
 
 
Dear Tom,
Thanks for your reply. 
You said that Shared Pool Latch is used to protect Memory Allocation. What does it mean ? Can you explain me one scenario when the memory allocation is to be protected so that it is clear for my understanding. 
What I have understood so far was
When a user fires a query then
1. Shared Pool Latch is acquired to check for the parsed verion of this SQL.
2. If the Parsed Version is available then Library Cache Latch is acquired to protect the parsed version of that SQL for any modification. (SOFT Parse).
3. If the parsed version is not available, even then the Library Cache latch is acquired to parse the query and generate the execution plan (HARD Parse)
Are my assumptions wrong. If yes, then which all latch will be acquired for each steps. Please let me know for better understanding.
Thanks and Regards
Vivek
 
 
June      29, 2004 - 8:04 am UTC 
 
the shared pool is a data structure.
people (processes, things, like dbwr, lgwr, etc) allocate memory from it to create data structures they need and use.
they that allocate memory from it, use a latch -- the shared pool latch.  In order to allocate memory from this shared data structure called the shared pool we need to latch it, serialize access to it -- to prevent two things from trying to modify this overall structure at the same time.
Now, later, after the memory is allocated, other things need to do stuff to it.  some of the memory that is allocated is used for a library cache.  In order to parse -- we need to access the library cache, a memory structure that happens to reside in the shared pool.  We use a library latch for that.
so, we use the library latch later when inspecting the library cache.  not the shared pool. when you have parsing issues (too much parsing, no binds, whatever) you see library latch contention.
if you have access to the book "Effective Oracle by Design", I describe the parsing process.  Also, "Beginning Oracle Programing" has similar information in a chapter I wrote. 
 
 
 
Shared Pool Latch Contention
Vivek Sharma, June      29, 2004 - 11:03 am UTC
 
 
Dear Tom,
Thanks for your reply. I understood the concept of Library Cache Latch and Shared Pool Latch now. Would like to know what all things to be taken care off if the database is experiencing heavy Shared Pool Latch Contention ? What should be tuned ?
Thanks and Regards
Vivek 
 
June      29, 2004 - 4:11 pm UTC 
 
have you ever seen heavy contention for this latch? 
 
 
 
Shared Pool Latch Contention
Vivek Sharma, June      30, 2004 - 2:08 am UTC
 
 
Dear Tom,
In the Statspack report "Latch Activity Section" it is written that PCT misses should be nearly 0 whereas the the pct misses on Library Cache and Shared Pool Latch are 1.8 and 2.1 respectively.
If the shared pool latch is used to allocate and protect memory allocation in the shared pool, then will the parameter parallel_automatic_tuning and configuring large_pool help eliminate the contention for this latch so that the memory for DBWR, LGWR and other processes are allocated in the large_pool.
Thanks and Regards
Vivek 
 
June      30, 2004 - 10:04 am UTC 
 
and what are the raw INPUT numbers to that percentage.  
You know, if I go for something twice, and miss it once -- that is 50% -- big deal.
soooo, what are the raw numbers, what are the waits on this, is it really impacting you.
ratios (pct's) are used to obscure and hide information -- it is near impossible to tune by them.  they can be used as red flags (if the pct goes from 0.00001 to 5, that would be a "flag") 
 
 
 
Dynamic SQL
Mike, July      15, 2004 - 11:42 pm UTC
 
 
there are some queries not using bind variables, I came to the developers for the issues. They claim becuase of using dynamic sql and there is no way to make the shared/bind work. 
How do you think of their claims?  
 
July      16, 2004 - 10:57 am UTC 
 
i think they need to read the documentation for this product they are using, just as much as they read their java or VB books.
using binds in dynamic sql is trivial -- nay, even EASIER than not using binds.
 
 
 
 
A reader, August    10, 2004 - 10:12 am UTC
 
 
Hi Tom,
 We are using Siebel CRM application and I want to use above technique to find sql statements which are not using  bind variable. Many of the sql generated by siebel is more then 1000 character long..In that case how could use remove_constants procedure and stuff..
Please help
Thanks 
 
August    10, 2004 - 10:22 am UTC 
 
you'd have to modify it to use  v$sqltext_with_newlines.
you could easily get up to 4000 characters via:
select address, hash_value,
max(decode(piece,0,sql_text)) || max(decode(piece,1,sql_text)) || max(decode(piece,2,sql_text)) ||
max(decode(piece,3,sql_text)) || max(decode(piece,4,sql_text)) || max(decode(piece,5,sql_text)) ||
max(decode(piece,6,sql_text)) || max(decode(piece,7,sql_text)) || max(decode(piece,8,sql_text)) ||
max(decode(piece,9,sql_text)) || max(decode(piece,10,sql_text)) || max(decode(piece,11,sql_text)) ||
max(decode(piece,12,sql_text)) || max(decode(piece,13,sql_text)) || max(decode(piece,14,sql_text)) ||
max(decode(piece,15,sql_text)) || max(decode(piece,16,sql_text)) || max(decode(piece,17,sql_text)) ||
max(decode(piece,18,sql_text)) || max(decode(piece,19,sql_text)) || max(decode(piece,20,sql_text)) ||
max(decode(piece,21,sql_text)) || max(decode(piece,22,sql_text)) || max(decode(piece,23,sql_text)) ||
max(decode(piece,24,sql_text)) || max(decode(piece,25,sql_text)) || max(decode(piece,26,sql_text)) ||
max(decode(piece,27,sql_text)) || max(decode(piece,28,sql_text)) || max(decode(piece,29,sql_text)) ||
max(decode(piece,30,sql_text)) || max(decode(piece,31,sql_text)) || max(decode(piece,32,sql_text)) ||
max(decode(piece,33,sql_text)) || max(decode(piece,34,sql_text)) || max(decode(piece,35,sql_text)) ||
max(decode(piece,36,sql_text)) || max(decode(piece,37,sql_text)) || max(decode(piece,38,sql_text)) ||
max(decode(piece,39,sql_text)) || max(decode(piece,40,sql_text)) || max(decode(piece,41,sql_text)) ||
max(decode(piece,42,sql_text)) || max(decode(piece,43,sql_text)) || max(decode(piece,44,sql_text)) ||
max(decode(piece,45,sql_text)) || max(decode(piece,46,sql_text)) || max(decode(piece,47,sql_text)) ||
max(decode(piece,48,sql_text)) || max(decode(piece,49,sql_text)) || max(decode(piece,50,sql_text)) ||
max(decode(piece,51,sql_text)) || max(decode(piece,52,sql_text)) || max(decode(piece,53,sql_text)) ||
max(decode(piece,54,sql_text)) || max(decode(piece,55,sql_text)) || max(decode(piece,56,sql_text)) ||
max(decode(piece,57,sql_text)) || max(decode(piece,58,sql_text)) || max(decode(piece,59,sql_text)) ||
max(decode(piece,61,sql_text))
from v$sqltext_with_newlines
group by address, hash_value
/
else, you are looking at a clob (not impossible, just more work) 
 
 
 
BIND VARIABLE and ORACLE FORMS
Deepak, August    11, 2004 - 5:21 pm UTC
 
 
Hi Tom,
I have a following code in Oracle Forms:
GO_BLOCK('BLOCK1') ;
SET_BLOCK_PROPERTY ('BLOCK1',default_where,'ref_key = ' || out_ref_key);
EXECUTE_QUERY;
This code always gets hard-parsed. Please suggest a way to Bind this query.
Thanks
Deepak 
 
August    12, 2004 - 8:32 am UTC 
 
'ref_key = :block.item'
will auto-bind for you.  use a "control block" (a block full of just items, not based on a table).  put out_ref_key into a field there and use :control_block.item_name 
 
 
 
As Always, TOM RULES !!!
Deepak, August    12, 2004 - 10:35 am UTC
 
 
Thank you tom. The Oracle Forms solution works.
I have a select statement on a lookup table which is called from 100's of different forms, Stored Procedures, Oracle Reports, Triggers etc...
Is it possible to FORCE cursor sharing for 1 single statement without changing the database parameter, so as not to affect cursor_sharing for other statements in the Database?
Deepak 
 
August    12, 2004 - 10:43 am UTC 
 
umm, if you have a single localized sql statement - why not just bind it and do it right in the first place?!? 
 
 
 
A reader, August    12, 2004 - 3:02 pm UTC
 
 
Because it is called from 1000's of different places. I mean,
Form1
  Program Unit 1
    select select_list from lu_table
    from type = 'TYPE1' and code = 'CODE1' ;
Form2
  Program Unit 1
    select select_list from lu_table
    from type = 'TYPE2' and code = 'CODE2' ;
...
...
Form n
  Program Unit X
    select select_list from lu_table
    from type = 'TYPEX' and code = 'CODEX' ;
same goes with Stored Procedures, Oracle Reports, Table Triggers.
 
 
August    12, 2004 - 3:32 pm UTC 
 
sooo, what you meant to say is:
I have hundreds of forms, stored procedures, reports, triggers etc that each have their own uniquely developed SQL
Not
I have a select statement on a lookup table which is called from 100's of 
different forms, Stored Procedures, Oracle Reports, Triggers etc...
You don't have "a select", you have "hundreds of them"
No, there is no magic that says "hey, when you see a query that looks like "select ... from lu_table where type = .... and code = ...."
Two bad things there -- they appear to have used a single code table for everything (hows that declarative integrity working out for you?  not!).  They didn't employ modular coding techniques.
Wait three -- they didn't bind...
Sorry -- no magic for this one -- they probably all have different whitespace anyhow, wouldn't make any difference
select * 
  from t
 where x = 5 and y = 10
is different from
select * 
  from t
 where x = 5
   and y = 10
is different from
Select * 
  from t
 where x = 5
   and y = 10
so -- it wouldn't do much anyway. 
 
 
 
A reader, August    12, 2004 - 3:52 pm UTC
 
 
In such a case, is it OK to go with CURSOR_SHARING=FORCE ? 
 
August    12, 2004 - 4:25 pm UTC 
 
I am reminded of a show I watched -- "Extreme Elimination" (if you haven't seen it, it is a Japanese series dubbed in english -- the contestants are made to do some pretty wacky things).
One of the contests was the person has to run full speed through a series of doors.  There are 3 walls one after the other.  Each wall has 3 doors.  The doors are covered in paper.  2 out of 3 of the doors are "open", the 3rd door is closed.
Contestant must run full speed through these doors.  If they hit paper all of the way, they win.  If they hit a locked wooden door (running at full speed remember), well -- they don't win.
That is what I think of when I think about cursor_sharing.
You need to test that -- everywhere.  It is not something you just turn on lightly.  Things will be affected by it.  I prefer for applications that are getting fixed to turn it on themselves (so as to not affect "good" applications) myself. 
 
 
 
A reader, September 15, 2004 - 11:54 am UTC
 
 
Tom,
After issuing 
select sql_text_wo_constants, count(*)
  from t1
 group by sql_text_wo_constants
having count(*) > 50
 order by 2
i noticed i have lot of entries like for different procedures
BEGIN MY_PROC_P1('#',:@,:RETCODE); END;       120
BEGIN MY_PROC-P2( '#', '#', '#', :@,           150
NULL, NULL, TO_DATE('#','#') );END;
As per my understanding procedures are autobinded, so why do i see entries like these.
Thanks.
 
 
September 15, 2004 - 11:58 am UTC 
 
your understanding is wrong.
the sql inside of a stored procedure (static sql) is "nicely bound as each reference to a plsql variable in a sql query is a bind variable"
but the CALLER of such procedures STILL NEEDS TO BIND THE CALL TO THE PROCEDURE itself!
The good news, if p1 has 10 queries, you have 1/10 of the problem you would have.  The coders have one statement to fix, not 10! 
 
 
 
A reader, September 15, 2004 - 12:07 pm UTC
 
 
Thanks for your prompt reply.
"but the CALLER of such procedures STILL NEEDS TO BIND THE CALL TO THE PROCEDURE 
itself!  "
does it mean bind variable has to be declared and then be passed to those procedures..
 
 
September 15, 2004 - 12:45 pm UTC 
 
yes, just like they bound:
BEGIN MY_PROC_P1('#',:@,:RETCODE); END;   
                        ^^^^^^^^
retcode they should be binding the first two inputs (geez, they know how to do this!  why didn't they just do it!) 
 
 
 
A reader, September 15, 2004 - 1:41 pm UTC
 
 
Much clearer now .. Thanks 
 
 
your final words are required.
Raaghid, December  22, 2004 - 4:26 am UTC
 
 
I attended a seminar (NOT from oracle corporation) on database maintenance. Session was ended with following conclusions.
1. Rollback segments to be defined as n/4 ("n" # of users and NOT exceeding 50)
2. Ideally database should have 4 control files and also should be in seperate hdd.
3. Extents calculation, make it as single extend etc. (Myself know that this is myth, since I have gone through your forum - so please ignore this point)
4. DB_BLOCK_BUFFERS is low, users will NOT have enought memory to operate efficently
DB_BLOCK_BUFFERS is high, your system may begin to swap and may come to halt
5. Read Hit ratio below 90 are usually a sign of poor indexing (But distortion of hit ratio number is possible)
6.Data dictionary cache miss ratio 90-95 % good
7. Library cache hit ratio > 95% good.
8. Increasing sort_area_size to reduce I/O and determine the PER USER space allocated in main memory for each process to sort.
 
 
December  22, 2004 - 9:38 am UTC 
 
1) rollback segments should be figured out by Oracle (automatic undo management)
2) 3 or 4, mostly 3 is what I see
3) silly
4) shows they have a firm grasp of the obvious :)
5) "read hit ratio"?
6) you want to miss 90/95% of the time?
7) and 96 is better
8) per user space, hmm, I thought it would be the per sort space and a user can have many of them -- but anyway -- pga_aggregate_target....
 
 
 
 
read hit ratio
Raaghid, December  23, 2004 - 5:02 am UTC
 
 
5) "read hit ratio"?
select (1-(sum(decode(name,'physical reads',value,0))/
(sum(decode(name,'db block gets',value,0))+
(sum(decode(name,'consistent gets',value,0))))))*100 Read_Hit_ratio
from v$sysstat;
6) you want to miss 90/95% of the time?
ohh. it is buffer miss followed by "hit ratio"
select sum(gets) gets, sum(getmisses) misses,
(1 - (sum(getmisses) /(sum(gets)+sum(getmisses))))*100 hit_ratio
from v$rowcache;
Point no. 5: Read hit ratio below 90-95 % means poor indexing. Do you agree? please answer.
 
 
December  23, 2004 - 11:24 am UTC 
 
5) that's a cache hit ratio isn't it.
No, I totally disagree that a hit ratio MEANS ANYTHING.
A hit ratio can be used like a flag.  My hit ratio suddenly changed from X to Y -- that is an indication that something "changed" -- maybe for the good, maybe for the bad.  It means something changed.
Using your logic, a hit ratio above 95% might mean I've overindexed :)
it might, it might not.   
 
 
 
Helena Marková, January   19, 2005 - 3:38 am UTC
 
 
 
 
bind result
Safrin, March     25, 2005 - 8:29 am UTC
 
 
I have checked our production server using your procedure remove_constants
results are:
select count(1) from t1;
resut --> 10990
select count(1) from
(select sql_text_wo_constants, count(*) cnt from t1
group by sql_text_wo_constants
having count(*) > 1
resut --> 481
select sum(cnt) from
(select sql_text_wo_constants, count(*) cnt from t1
group by sql_text_wo_constants
having count(*) > 1
result --> 8157
total parsing sqls - 10,990
sqls having repeated parsing - 481
sql repeated parsing with no. of times - 8157
(ie instead of 481, 8157 times parsed)
ratio =  ( 481 / (10990- (8157-481)) )*100
      = 14.51 %
Hence our production server sqls approx 85 % bind enabled and 15 % of places, still to be changed to make it as "bind enabled". 
(So I have to take list sqls repeated in table t1 (arrived using remove constants) and I have to take it up with development team for changing the same.)
Please confirm my calculation above.
 
 
March     25, 2005 - 6:14 pm UTC 
 
you cannot compute a ratio from that, you can only compute what percentage of the shared pool CURRENTLY is "bind friendly" and "not bind friendly"
for the "not bind friendly" will kick out bind friendly statements.
but you do seem to have the ratios backwards.
If 8,157 statements are in there that are the same except for literls (potential non-bind friendly statements) and you have 11,000 statements in there -- about 85% of them are "not bind friendly" 
 
 
 
exactly
riyaz, March     27, 2005 - 7:21 am UTC
 
 
Exactly it is only tells how much % friendly bind sqls are there.
Thanks.
Then how to find out ratio. 
 
March     27, 2005 - 10:22 am UTC 
 
it is a binary thing.
You either have bind friendly sql
or you don't
that sql which is not bind friendly needs to be reviewed to see if it should be. 
 
 
 
Library Cache Latch contention
tom evans, May       12, 2005 - 10:03 am UTC
 
 
Hi Tom,
We have severe problems revolving around Library Cache latch waits / sleeps. I wonder if you know of any way of finding the amount of time a Library Cache child latch is held,(which we have identified as #106), and to identify the respective SQL statements, in version 8.1.7.4.
I do appreciate that we are dealing with microseconds, but this child is using approx 97% of the waits on the system and we would hope therefore that it will repeat and / or be holding the child latch for a longer time.
We have already reduced the Library Cache Latch requests by over 40%, by code optimisation (less executions/more soft parses), but the sleeps have not decreased at all.  
 
May       12, 2005 - 1:08 pm UTC 
 
can you define "severe" -- where you are and where you need to get to go.
the executions are not a problem, it is the PARSE 
your goal would be the parse once and execute it over and over and over.  (soft parses are bad parses, hard parses are just worst bad parses)
do you have a pretty bad hard parse problem still?
The latches are held for incredibly small periods of time (hopefully), they are not tracked at that level.  
 
 
 
dynamic sql and bind variable
reader, May       19, 2005 - 12:04 pm UTC
 
 
Tom,
We have very complicated pl/sql package in which the developer use the dynamic sql to insert data into the global temp table. This is used all day in our OLTP enviornment where application users search for the person with different input. When we had checked the statement
exececute and counts are same around 6000 meaning that many different versions of the sql in the cache instead of 1 or 2.
I had used the following query,
 
SELECT substr(sql_text,1,40) "SQL", count(*) , 
                 sum(executions) "TotExecs"
            FROM v$sqlarea
           WHERE executions < 5
           GROUP BY substr(sql_text,1,40)
          HAVING count(*) > 30
           ORDER BY 2;                                  
The code in PL/SQL package, is there any way we can tune this??
     v_InsertStmt :=    'INSERT INTO temp_person_search   
                         (sequence_id, ' ||                      'membership_number, ' ||                   'account_individuals, ' ||                   'date_of_births, ' ||
                'ages, ' ||
                'address, ' ||
                'phone_numbers, ' ||
                'household_id, ' ||
                'sort_individual_id) ' ||
                 '(SELECT ' || v_SequenceID || ', ' ||
        'pkg_person_search.fn_get_current_member_num(h1.household_id), ' ||
        'pkg_person_search.fn_get_household_members(h1.household_id), ' ||                'pkg_person_search.fn_get_hhld_mem_birth_date(h1.household_id), ' ||
        'pkg_person_search.fn_get_hhld_mem_age(h1.household_id), ' ||
        'pkg_person_search.fn_get_household_address(h1.household_id), ' ||                'pkg_person_search.fn_get_household_phone_nums(h1.household_id), ' || 'h1.household_id, ' ||
    'pkg_person_search.fn_get_result_order_indv_id(h1.household_id) ' ||
    'FROM         household h1  ' ||
    'WHERE     h1.household_id IN (' || v_SQLStmt || '))';
    EXECUTE IMMEDIATE v_InsertStmt; 
 
 
The function won't work in our case
reader, May       19, 2005 - 5:29 pm UTC
 
 
Tom,
Thanks for the reply, but in our case the function and casting won't work as we build the where condition based on the customer input that input is different everytime 
WHERE  h1.household_id IN 
( SELECT household_id FROM ( SELECT DISTINCT(h.household_Id) FROM household h WHERE (h.daytime_phone_num = '8454571465' OR h.evening_phone_num = '8454571465') ) WHERE ROWNUM < 253 ))
Another example 
WHERE  h1.household_id IN (   SELECT household_id FROM ( SELECT DISTINCT(h.household_Id) FROM household h WHERE h.current_bank_acct_num = '03173219' ) WHERE ROWNUM < 253 )) 
 
May       20, 2005 - 7:05 am UTC 
 
 
 
getting error while casting in sys_context
Vrajesh, May       25, 2005 - 5:26 pm UTC
 
 
I am geeting error while using casting with sys_context.
                                      VAR1                                       
-----
1,2,3,4                                                     
SELECT count(*) 
FROM work_queue_item wqi, work_queue_status wqs 
WHERE wqi.status_id = wqs.status_id 
AND wqi.status_id IN (select * from table ( CAST( str2tbl ( sys_context( 'WQ_CTX', 's_status_id' ) ) as str2tableType )))
The wqi.status_id is Number data type.
 
The context was set in same session tho' pl/sql procedure. I was getting ORA-00902: invalid datatype error both way. Could you please show me where I am doing wrong?
Thanks,
  
 
May       25, 2005 - 8:05 pm UTC 
 
type name is probably str2TBLtype, not TABLE
 
 
 
 
same as above
Vrajesh, May       25, 2005 - 5:34 pm UTC
 
 
As continue for above question why I need to cast?
Why the following statement not work for above conext value.
SELECT count(*) FROM work_queue_item wqi,work_queue_status wqs WHERE wqi.status_id = wqs.status_id 
AND wqi.status_id IN  ( to_number(sys_context( 'WQ_CTX', 's_status_id' )) )
 
 
May       25, 2005 - 8:05 pm UTC 
 
cast is needed in older releases and sometimes in plsql, hence I tend to use it. 
 
 
 
shay ittah, May       30, 2005 - 4:55 am UTC
 
 
Hi Tom,
I am running this query :
select  w.sid,
        c.name || ' (child #' || c.child# || ')' latch,
        s.program,
        s.machine || ', ' || s.process process,
        p.spid ospid,
        a.sql_text,
        a.hash_value,
        a.parse_calls,
        a.executions
from    v$session_wait          w,
        v$latch_children        c,
        v$session               s,
        v$process               p,
        v$sqlarea               a
where   w.event = 'latch free'
and     c.addr = w.p1raw
and     s.sid = w.sid
and     p.addr = s.paddr
and     a.address (+) = s.sql_address
/
and the output is 
   397 library    iwserver@r3d3   r3d3,    13201     Begin                          1055490975        6902      13560
       cache      (TNS V1-V3)     25409              Ptsm_Vas_General_Services3_Pkg
       (child #7)                                    .Ptsm_GeneralServices_Validate
                                                     (:txt0, :txt1,:txt2, :a0, :a1,
                                                     :a2, :a3, :a4,:b, :r, :s);
                                                     End;
   567 library    iwserver@r3d3   r3d3,    3032      Begin                          1055490975        6902      13560
       cache      (TNS V1-V3)     2681               Ptsm_Vas_General_Services3_Pkg
       (child #1)                                    .Ptsm_GeneralServices_Validate
                                                     (:txt0, :txt1,:txt2, :a0, :a1,
                                                     :a2, :a3, :a4,:b, :r, :s);
                                                     End;
same statement / same hash_value different childs?
How come? 
 
May       30, 2005 - 9:02 am UTC 
 
you know, I really cannot make heads or tails of that output.
</code>  
http://asktom.oracle.com/~tkyte/print_table/  <code>
try printing "down" the page.
but also try using "length" and "dump" on the SQL text and look for obvious differences.  
 
 
over 22 seconds on nam='latch: library cache'
A reader, July      09, 2005 - 5:17 pm UTC
 
 
Here is the version:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - 64bi
PL/SQL Release 10.1.0.3.0 - Production
CORE    10.1.0.3.0      Production
TNS for Solaris: Version 10.1.0.3.0 - Production
NLSRTL Version 10.1.0.3.0 - Production
Here is the trace file:
=====================
PARSING IN CURSOR #1 len=65 dep=0 uid=220 oct=6 lid=220 tim=387747479508 hv=4170283050 ad='9ae98b90'
update cust set lastLogin = sysdate where customer_id = :cid
END OF STMT
PARSE #1:c=0,e=93,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=387747479495
*** 2005-07-08 14:18:01.567
<b>WAIT #1: nam='latch: library cache' ela= 22360910 </b>p1=24488193544 p2=199 p3=0
BINDS #1:
 bind 0: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=00 oacfl2=0000 size=24 offset=0
   bfp=ffffffff7bb6d2a0 bln=22 avl=06 flg=05
   value=103313413
WAIT #1: nam='buffer busy waits' ela= 77925 p1=159 p2=392206 p3=1
WAIT #1: nam='buffer busy waits' ela= 12791 p1=547 p2=710649 p3=1
WAIT #1: nam='enq: TX - index contention' ela= 11388 p1=1415053316 p2=4587522 p3=301972
WAIT #1: nam='latch: enqueue hash chains' ela= 7739 p1=24840189800 p2=20 p3=0
EXEC #1:c=20000,e=22479366,p=0,cr=11,cu=17,mis=0,r=1,dep=0,og=1,tim=387769959129
WAIT #1: nam='SQL*Net message to client' ela= 9 p1=1413697536 p2=1 p3=0
WAIT #1: nam='SQL*Net message from client' ela= 453 p1=1413697536 p2=1 p3=0
STAT #2 id=1 cnt=0 pid=0 pos=1 obj=0 op='COUNT STOPKEY (cr=31 pr=0 pw=0 time=1043 us)'
STAT #2 id=2 cnt=0 pid=1 pos=1 obj=22585 op='TABLE ACCESS FULL WG2K_PLAYER_LOCKOUT (cr=31 pr=0 pw=0 time=1034 us)'
=====================
PARSING IN CURSOR #2 len=105 dep=0 uid=220 oct=3 lid=220 tim=387769961679 hv=1751757214 ad='9c679790'
select work, round_id, version, revision, variation, flags from work_in_progress where customer_id = :1
END OF STMT
PARSE #2:c=0,e=200,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=387769961661
BINDS #2:
 bind 0: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=00 oacfl2=0000 size=24 offset=0
   bfp=ffffffff7bb5ff78 bln=22 avl=06 flg=05
   value=103313413
EXEC #2:c=0,e=555,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=387769962607
WAIT #2: nam='SQL*Net message to client' ela= 4 p1=1413697536 p2=1 p3=0
FETCH #2:c=0,e=123,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=1,tim=387769963173
WAIT #2: nam='SQL*Net message from client' ela= 449 p1=1413697536 p2=1 p3=0
XCTEND rlbk=0, rd_only=0
WAIT #0: nam='log file sync' ela= 7090 p1=3563 p2=0 p3=0
WAIT #0: nam='SQL*Net message to client' ela= 5 p1=1413697536 p2=1 p3=0
WAIT #0: nam='SQL*Net message from client' ela= 418 p1=1413697536 p2=1 p3=0
XCTEND rlbk=1, rd_only=1
WAIT #0: nam='SQL*Net message to client' ela= 9 p1=1413697536 p2=1 p3=0
WAIT #0: nam='SQL*Net message from client' ela= 486 p1=1413697536 p2=1 p3=0
XCTEND rlbk=1, rd_only=1
WAIT #0: nam='SQL*Net message to client' ela= 3 p1=1413697536 p2=1 p3=0
WAIT #0: nam='SQL*Net message from client' ela= 768 p1=1413697536 p2=1 p3=0
STAT #1 id=1 cnt=0 pid=0 pos=1 obj=0 op='UPDATE  (cr=11 pr=0 pw=0 time=114758 us)'
STAT #1 id=2 cnt=1 pid=1 pos=1 obj=16837 op='TABLE ACCESS BY INDEX ROWID cust (cr=5 pr=0 pw=0 time=529 us)'
STAT #1 id=3 cnt=1 pid=2 pos=1 obj=52162 op='INDEX RANGE SCAN cust_IDX001 (cr=3 pr=0 pw=0 time=149 us)'
=====================
Any idea why Oracle spent so long on library cache latch considering that we're already using bind variables?
and why Oracle emited '*** 2005-07-08 14:18:01.567' before that waits?
Thanks a lot in advance 
 
 
July      10, 2005 - 9:20 am UTC 
 
a parse is a parse is a parse is a parse.  There are types of parses, hard and soft, soft being better than hard, but a parse is a parse is a parse.  binds or not.  It is a parse and as such, must do significant latching into the shared pool to process.
is your system suffering from "lots of parsing", tons of parsing
and don't you wish every line had that nice timestamp, I sure do. 
 
 
 
Remove_constants with multibyte characters
Neelz, July      20, 2005 - 4:18 am UTC
 
 
Dear Tom
I was trying to find out the Sql statements not using bind variables with the procedure you had given. When I execute the function it returns with error ORA-06502. It is because of using multibyte characters(Japanese) in the query like table names or column names. Could you please help me with a solution for this. 
For example:
select remove_constants('L') from dual;
gives error ORA-06502.
Thanks & Regards
 
 
July      20, 2005 - 6:28 am UTC 
 
the code is not that complex, can you take a look at it and sort of debug it? 
 
 
 
library cache latch contention
A reader, July      26, 2005 - 3:10 pm UTC
 
 
we are seeing a lots of 'latch free' waits. Its the #1 wait. The cause is library cache latch contention. Its not practicle to change the code at the moment. The system is very complex. Any way to reduce the library cache latch waits? 
 
July      26, 2005 - 3:29 pm UTC 
 
what is causing the library cache latch contention:
a) excessive soft parsing
b) excessive hard parsing
and -- do you have a test system that you can load up to, well, test a parameter change on. 
 
 
 
A reader, July      26, 2005 - 5:20 pm UTC
 
 
There is no hard parsing at all.
We have cursor_sharing=SIMILAR
We don't have a test system where we can practically test anything. We'll hv to do it in production.
Load Profile
~~~~~~~~~~~~                            Per Second       Per Transaction
                                   ---------------       ---------------
                  Redo size:             58,660.73              1,936.94
              Logical reads:             10,185.88                336.33
              Block changes:                343.58                 11.34
             Physical reads:                429.88                 14.19
            Physical writes:                 40.21                  1.33
                 User calls:              3,393.25                112.04
                     Parses:                910.57                 30.07
                Hard parses:                  0.02                  0.00
                      Sorts:                 51.59                  1.70
                     Logons:                  0.12                  0.00
                   Executes:              1,643.58                 54.27
               Transactions:                 30.29
  % Blocks changed per Read:    3.37    Recursive Call %:                34.87
 Rollback per transaction %:    1.90       Rows per Sort:                23.03
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %:   99.71       Redo NoWait %:               99.97
            Buffer  Hit   %:   95.78    In-memory Sort %:              100.00
            Library Hit   %:  100.47        Soft Parse %:              100.00
         Execute to Parse %:   44.60         Latch Hit %:               98.76
Parse CPU to Parse Elapsd %:    2.10     % Non-Parse CPU:               94.78
 Shared Pool Statistics        Begin   End
                               ------  ------
             Memory Usage %:   71.22   71.42
    % SQL with executions>1:   77.44   77.36
  % Memory for SQL w/exec>1:   76.06   75.95
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~                                                     % Total
Event                                               Waits    Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
latch free                                      1,008,928     109,850    33.27
enqueue                                           126,613      62,231    18.84
buffer busy waits                                  51,496      38,175    11.56
db file sequential read                           738,505      32,484     9.84
free buffer waits                                  31,495      30,784     9.32
          -------------------------------------------------------------
 
 
July      26, 2005 - 5:54 pm UTC 
 
 Parses:                910.57                 30.07
ouch, that hurts doesn't it.  
what do you have session cached cursors set to?  what is the session cursor cache hits|count statistic showing? 
 
 
 
session wait
abc, July      27, 2005 - 3:34 pm UTC
 
 
       SID       SEQ# EVENT                P1TEXT             P1 P1RAW            P2TEXT                
---------- ---------- -------------------- ---------- ---------- ---------------- ------------------
         1      58267 pmon timer           duration          300 000000000000012C                       
         2      39979 rdbms ipc message    timeout           300 000000000000012C                       
         3      22189 rdbms ipc message    timeout            69 0000000000000045                       
         6        528 rdbms ipc message    timeout        180000 000000000002BF20                       
         4      42730 rdbms ipc message    timeout           300 000000000000012C                       
         9      47573 db file sequential r file#             245 00000000000000F5 block#                
                      ead
        18      31212 db file sequential r file#             277 0000000000000115 block#                
                      ead
        13        270 PX Deq: Txn Recovery sleeptime/        200 00000000000000C8 passes                
                       Start               senderid
        14        270 PX Deq: Txn Recovery sleeptime/        200 00000000000000C8 passes                
                       Start               senderid
        22        270 PX Deq: Txn Recovery sleeptime/        200 00000000000000C8 passes                
                       Start               senderid
         5       8597 wait for stopper eve                     0 00                                     
                      nt to be increased
        23        328 SQL*Net message to c driver id  1413697536 0000000054435000 #bytes                
                      lient
         7       2677 SQL*Net message from driver id   675562835 0000000028444553 #bytes                
                       client
        10       3009 SQL*Net message from driver id  1413697536 0000000054435000 #bytes                
                       client
        16      14370 SQL*Net message from driver id  1413697536 0000000054435000 #bytes                
                       client
        20       1448 SQL*Net message from driver id  1413697536 0000000054435000 #bytes                
                       client
        17       8526 SQL*Net message from driver id  1413697536 0000000054435000 #bytes                
                       client
        11       4241 SQL*Net message from driver id   675562835 0000000028444553 #bytes                
                       client
        12       3078 SQL*Net message from driver id  1413697536 0000000054435000 #bytes                
                       client
Tom ,Please give your comments on above 
 
July      27, 2005 - 3:51 pm UTC 
 
looks like the output of a query to me?  not sure what you want me to say.   
 
 
 
A reader, July      28, 2005 - 11:43 am UTC
 
 
<Tom>
Parses:                910.57                 30.07
ouch, that hurts doesn't it.  
what do you have session cached cursors set to?  what is the session cursor 
cache hits|count statistic showing? 
</Tom>
session cached cursors is not set. We tried to set it to 100 , but doesn't look like it helped.
what is the session cursor cache hits|count statistic showing? --- Where do i see it? 
 
July      28, 2005 - 12:15 pm UTC 
 
it would be in the statspack report along with all of the other statistics. 
 
 
 
A reader, July      28, 2005 - 12:58 pm UTC
 
 
Statistic                                      Total     per Second    per Trans
--------------------------------- ------------------ -------------- ------------
CPU used by this session                     980,970          546.5         18.1
CPU used when call started                   980,949          546.5         18.0
CR blocks created                              5,850            3.3          0.1
Cached Commit SCN referenced                   1,218            0.7          0.0
Commit SCN cached                                 89            0.1          0.0
DBWR buffers scanned                               0            0.0          0.0
DBWR checkpoint buffers written               33,798           18.8          0.6
DBWR checkpoints                                   2            0.0          0.0
DBWR cross instance writes                        25            0.0          0.0
DBWR free buffers found                            0            0.0          0.0
DBWR fusion writes                            10,635            5.9          0.2
DBWR lru scans                                    18            0.0          0.0
DBWR make free requests                           72            0.0          0.0
DBWR revisited being-written buff                  1            0.0          0.0
DBWR summed scan depth                             0            0.0          0.0
DBWR transaction table writes                    230            0.1          0.0
DBWR undo block writes                         4,017            2.2          0.1
DFO trees parallelized                            19            0.0          0.0
PX local messages recv'd                          86            0.1          0.0
PX local messages sent                            86            0.1          0.0
PX remote messages recv'd                         92            0.1          0.0
PX remote messages sent                           69            0.0          0.0
Parallel operations downgraded to                  0            0.0          0.0
Parallel operations not downgrade                 19            0.0          0.0
RowCR - row contention                            25            0.0          0.0
RowCR attempts                                 1,009            0.6          0.0
RowCR hits                                       952            0.5          0.0
SQL*Net roundtrips to/from client          5,984,253        3,333.9        110.1
active txn count during cleanout              10,243            5.7          0.2
background checkpoints completed                   1            0.0          0.0
background checkpoints started                     2            0.0          0.0
background timeouts                            2,148            1.2          0.0
branch node splits                                 5            0.0          0.0
buffer is not pinned count                 9,944,004        5,539.8        182.9
buffer is pinned count                     4,560,050        2,540.4         83.9
bytes received via SQL*Net from c        530,065,085      295,300.9      9,750.7
bytes sent via SQL*Net to client         841,800,537      468,969.7     15,485.1
calls to get snapshot scn: kcmgss          3,457,742        1,926.3         63.6
calls to kcmgas                              252,079          140.4          4.6
calls to kcmgcs                                4,396            2.5          0.1
change write time                             32,627           18.2          0.6
cleanout - number of ktugct calls              9,568            5.3          0.2
cleanouts and rollbacks - consist              5,216            2.9          0.1
cleanouts only - consistent read                 342            0.2          0.0
cluster key scan block gets                  260,623          145.2          4.8
cluster key scans                            151,531           84.4          2.8
commit cleanout failures: block l                 54            0.0          0.0
commit cleanout failures: buffer                  25            0.0          0.0
commit cleanout failures: callbac                 21            0.0          0.0
commit cleanout failures: cannot                 159            0.1          0.0
commit cleanouts                             141,756           79.0          2.6
commit cleanouts successfully com            141,497           78.8          2.6
commit txn count during cleanout               2,120            1.2          0.0
consistent changes                            10,281            5.7          0.2
consistent gets                           17,630,040        9,821.8        324.3
consistent gets - examination              8,444,648        4,704.5        155.3
Instance Activity Stats for DB: ECA  Instance: eca1  Snaps: 22323 -22324
Statistic                                      Total     per Second    per Trans
--------------------------------- ------------------ -------------- ------------
current blocks converted for CR                    1            0.0          0.0
cursor authentications                            14            0.0          0.0
data blocks consistent reads - un             10,047            5.6          0.2
db block changes                             616,730          343.6         11.3
db block gets                                670,863          373.7         12.3
deferred (CURRENT) block cleanout             66,423           37.0          1.2
dirty buffers inspected                      108,718           60.6          2.0
enqueue conversions                              405            0.2          0.0
enqueue deadlocks                                  5            0.0          0.0
enqueue releases                             232,629          129.6          4.3
enqueue requests                             231,908          129.2          4.3
enqueue timeouts                                   3            0.0          0.0
enqueue waits                                 17,058            9.5          0.3
exchange deadlocks                            17,159            9.6          0.3
execute count                              2,950,234        1,643.6         54.3
free buffer inspected                      1,527,907          851.2         28.1
free buffer requested                      1,049,648          584.8         19.3
gcs messages sent                            956,297          532.8         17.6
ges messages sent                             56,557           31.5          1.0
global cache blocks lost                          65            0.0          0.0
global cache convert time                    658,050          366.6         12.1
global cache converts                         73,128           40.7          1.4
global cache cr block build time               6,703            3.7          0.1
global cache cr block flush time              24,781           13.8          0.5
global cache cr block receive tim             65,111           36.3          1.2
global cache cr block send time               11,616            6.5          0.2
global cache cr blocks received               41,016           22.9          0.8
global cache cr blocks served                 74,157           41.3          1.4
global cache current block flush              32,034           17.9          0.6
global cache current block pin ti          1,903,565        1,060.5         35.0
global cache current block receiv            354,068          197.3          6.5
global cache current block send t              7,540            4.2          0.1
global cache current blocks recei            103,002           57.4          1.9
global cache current blocks serve             43,077           24.0          0.8
global cache defers                              313            0.2          0.0
global cache freelist waits                      144            0.1          0.0
global cache get time                      1,082,145          602.9         19.9
global cache gets                            840,060          468.0         15.5
global cache prepare failures                      0            0.0          0.0
global cache skip prepare failure             25,111           14.0          0.5
global lock async converts                       733            0.4          0.0
global lock async gets                           483            0.3          0.0
global lock convert time                       1,712            1.0          0.0
global lock get time                       5,553,240        3,093.7        102.2
global lock releases                         740,602          412.6         13.6
global lock sync converts                      1,311            0.7          0.0
global lock sync gets                        740,244          412.4         13.6
hot buffers moved to head of LRU             365,778          203.8          6.7
immediate (CR) block cleanout app              5,577            3.1          0.1
immediate (CURRENT) block cleanou             16,050            8.9          0.3
index fast full scans (full)                       1            0.0          0.0
index fetch by key                         2,043,240        1,138.3         37.6
index scans kdiixs1                        1,258,729          701.2         23.2
leaf node 90-10 splits                            22            0.0          0.0
leaf node splits                                 105            0.1          0.0
logons cumulative                                221            0.1          0.0
Instance Activity Stats for DB: ECA  Instance: eca1  Snaps: 22323 -22324
Statistic                                      Total     per Second    per Trans
--------------------------------- ------------------ -------------- ------------
messages received                             17,597            9.8          0.3
messages sent                                 17,597            9.8          0.3
no buffer to keep pinned count                     0            0.0          0.0
no work - consistent read gets             6,807,056        3,792.2        125.2
opened cursors cumulative                  1,411,846          786.5         26.0
parse count (failures)                             6            0.0          0.0
parse count (hard)                                30            0.0          0.0
parse count (total)                        1,634,474          910.6         30.1
parse time cpu                                51,185           28.5          0.9
parse time elapsed                         2,435,356        1,356.7         44.8
physical reads                               771,637          429.9         14.2
physical reads direct                             95            0.1          0.0
physical writes                               72,171           40.2          1.3
physical writes direct                            65            0.0          0.0
physical writes non checkpoint                70,309           39.2          1.3
pinned buffers inspected                     418,098          232.9          7.7
prefetch clients - default                         6            0.0          0.0
prefetched blocks                             19,697           11.0          0.4
prefetched blocks aged out before                 37            0.0          0.0
process last non-idle time           252,581,568,265  140,713,965.6  4,646,289.1
queries parallelized                              19            0.0          0.0
recursive calls                            3,261,006        1,816.7         60.0
recursive cpu usage                          448,622          249.9          8.3
redo blocks written                          220,573          122.9          4.1
redo buffer allocation retries                    52            0.0          0.0
redo entries                                 326,144          181.7          6.0
redo log space requests                           89            0.1          0.0
redo log space wait time                       1,341            0.8          0.0
redo ordering marks                            4,253            2.4          0.1
redo size                                105,296,012       58,660.7      1,936.9
redo synch time                            1,693,641          943.5         31.2
redo synch writes                             54,058           30.1          1.0
redo wastage                               4,083,300        2,274.8         75.1
redo write time                              140,164           78.1          2.6
redo writer latching time                      3,892            2.2          0.1
redo writes                                   15,688            8.7          0.3
remote instance undo block writes                 25            0.0          0.0
rollback changes - undo records a              9,615            5.4          0.2
rollbacks only - consistent read                 605            0.3          0.0
rows fetched via callback                  1,296,280          722.2         23.9
session connect time                 278,351,372,041  155,070,402.3  5,120,329.9
session logical reads                     18,283,663       10,185.9        336.3
session pga memory max                    52,871,856       29,455.1        972.6
session uga memory                        26,238,760       14,617.7        482.7
session uga memory max                   107,014,712       59,618.2      1,968.6
shared hash latch upgrades - no w          1,775,368          989.1         32.7
shared hash latch upgrades - wait                635            0.4          0.0
sorts (disk)                                       0            0.0          0.0
sorts (memory)                                92,599           51.6          1.7
sorts (rows)                               2,133,009        1,188.3         39.2
summed dirty queue length                    916,778          510.7         16.9
switch current to new buffer                  83,353           46.4          1.5
table fetch by rowid                       5,184,007        2,888.0         95.4
table fetch continued row                     88,547           49.3          1.6
table scan blocks gotten                   2,853,247        1,589.6         52.5
table scan rows gotten                     2,460,559        1,370.8         45.3
Instance Activity Stats for DB: ECA  Instance: eca1  Snaps: 22323 -22324
Statistic                                      Total     per Second    per Trans
--------------------------------- ------------------ -------------- ------------
table scans (long tables)                          0            0.0          0.0
table scans (short tables)                   354,522          197.5          6.5
transaction lock background get t                  1            0.0          0.0
transaction lock background gets                 136            0.1          0.0
transaction lock foreground reque                136            0.1          0.0
transaction lock foreground wait               1,029            0.6          0.0
transaction rollbacks                            729            0.4          0.0
user calls                                 6,090,875        3,393.3        112.0
user commits                                  53,328           29.7          1.0
user rollbacks                                 1,034            0.6          0.0
workarea executions - onepass                      0            0.0          0.0
workarea executions - optimal                184,874          103.0          3.4
write clones created in backgroun                  1            0.0          0.0
write clones created in foregroun              1,542            0.9          0.0
          -------------------------------------------------------------
 
 
July      28, 2005 - 1:19 pm UTC 
 
a simple "i don't see it in there" would suffice ;)
select * from v$sysstat where name like 'session%';
wait a bit.
do the query again
subtract the results of the first query from the second, that'll show if you are getting any session cache hits
and you do have the parameter set to a non zero number right. 
 
 
 
A reader, July      28, 2005 - 4:06 pm UTC
 
 
STATISTIC# NAME                                                                  CLASS      VALUE
---------- ---------------------------------------------------------------- ---------- ----------
       208 session cursor cache hits                                                64          0
       209 session cursor cache count                                               64          0 
 
July      29, 2005 - 7:31 am UTC 
 
and, do you have session_caches_cursors *SET* or not. 
 
 
 
A reader, July      29, 2005 - 10:00 am UTC
 
 
<do you have session_caches_cursors *SET* or not.>
No.
However, we tried it setting to a value of 100 in QA Stress region, but did not find any difference. 
 
July      29, 2005 - 12:32 pm UTC 
 
define "did not find any difference"
you obviously won't have any hits or anything if it is not set (thought that was obvious anyway).
 
 
 
 
A reader, July      29, 2005 - 12:31 pm UTC
 
 
Can someone who is running 9i RAC on Solaris share his statspack report with me. I just want to compare ours to get an idea whether our values are similar or way-off. Also, it'll be helpful if you can mention how many CPUs you have and how much is your cpu utilization?
Thanks in advance.  
 
July      29, 2005 - 2:55 pm UTC 
 
statspacks are like fingerprints.
unless they are running YOUR application, there is no chance I would expect them to correlate even a little bit. 
 
 
 
A reader, August    01, 2005 - 5:23 pm UTC
 
 
<do you have session_caches_cursors *SET* or not.>
No.
However, we tried it setting to a value of 100 in QA Stress region, but did not 
find any difference. 
Followup:
define "did not find any difference"
-- Test was done by my colleague and he said he did not find any difference in terms of (i) perses/second (ii) library cache latch free waits and (iii) CPU utilization.
  
 
August    01, 2005 - 8:44 pm UTC 
 
did they measure if it was getting "hit", eg: USED
if not, I would agree with their assement
if it was, I would not.
but that aside, it seems you've already tested that and there is no opportunity for cursor caching here.
back to vendor.  no magic. 
 
 
 
dave
uk, October   10, 2005 - 7:15 am UTC
 
 
Hi Tom, when trying to run your example at the top I get this 9.2.0.5 Linux Redhat
SQL> create table t1 as select sql_text from v$sqlarea;
Table created.
SQL> alter table t1 add sql_text_wo_constants varchar2(1000);
Table altered.
SQL> create or replace function
  2  remove_constants( p_query in varchar2 ) return varchar2
  3  as
  4      l_query long;
  5      l_char  varchar2(1);
  6      l_in_quotes boolean default FALSE;
  7  begin
  8      for i in 1 .. length( p_query )
  9      loop
 10          l_char := substr(p_query,i,1);
 11          if ( l_char = '''' and l_in_quotes )
 12          then
 13              l_in_quotes := FALSE;
 14          elsif ( l_char = '''' and NOT l_in_quotes )
 15          then
 16              l_in_quotes := TRUE;
 17              l_query := l_query || '''#';
 18          end if;
 19          if ( NOT l_in_quotes ) then
 20              l_query := l_query || l_char;
 21          end if;
 22      end loop;
 23      l_query := translate( l_query, '0123456789', '@@@@@@@@@@' );
 24      for i in 0 .. 8 loop
 25          l_query := replace( l_query, lpad('@',10-i,'@'), '@' );
 26          l_query := replace( l_query, lpad(' ',10-i,' '), ' ' );
 27      end loop;
 28      return upper(l_query);
 29  end;
 30  /
Function created.
SQL>
SQL> update t1 set sql_text_wo_constants = remove_constants(sql_text);
update t1 set sql_text_wo_constants = remove_constants(sql_text)
                                      *
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "PERFSTAT.REMOVE_CONSTANTS", line 10
If i change
 
l_char  varchar2(1);
to l_char  varchar2(10);
it works but I am unsure if I have 'broken' anything
Thanks
 
 
 
October   10, 2005 - 9:01 am UTC 
 
you have a multibyte character set.... your fix was good - or you could have
ops$tkyte@ORA10GR2> declare l_char varchar2(1 CHAR ); begin null; end;
  2  /
 
PL/SQL procedure successfully completed.
varchar2(1 CHAR) 
 
 
 
 
not a bind variable problem
A reader, November  01, 2005 - 3:22 pm UTC
 
 
I have library cache contention but no bind variable issues, or should I say it doesn't look like any serious bind variable issues. Can it be something else? I ran your script, the max number of duplicate statements was 4 closely followed by some 2's, and there were only about 80 statments, yet everything is sitting on a latch free library cache event.  in just 9 sessions.  Shared pool is 150MB.  
 
November  02, 2005 - 4:55 am UTC 
 
how often do you parse.  a parse is a parse is a parse is lots of latching. 
 
 
 
Native Dynamic SQL
Andrew Markiewicz, November  03, 2005 - 10:15 am UTC
 
 
Tom,
In Ch.9 of your book Effective Oracle By Design, you mention that native dynamic sql is parsed every time.  I've noticed an increase in latch free wait events when a program that uses excessive NDS is run even though the sql uses binds.
Could that be the source of the latch contention?
 
 
November  04, 2005 - 2:35 am UTC 
 
(and that is true in 9i - in 10g, it is not "as true" - 10g can reuse sql --
for i in 1 .. 100
loop
   execute immmediate 'insert into t values ( :x )' values i;
end loop;
in 9i - 100 parses, in 10g 1 parse at most
for i in 1 .. 100
loop
   execute immmediate 'insert into t t' || mod(i,2) || ' values ( :x )' values i;
end loop;
in 9i - 100 parses, in 10g 100 parses - because the sql statement flip flops between 'insert into t t0' and 'insert into t t1' every time.....
In short:
hard parsing - very very bad.
soft parsing - very bad.
no parse - good.......
Yes, the soft parses can definitely do that, in 9i, you would consider dbms_sql so you can parse once and execute many.
 
 
 
 
bind variable 
K.P.VIDYADHARAN, December  02, 2005 - 2:42 am UTC
 
 
I really understood the concept and I was able to find
out the sql which is causing high parsing
Thanks....TOM
 
 
 
transaction allocation latch#134
jianhui, January   26, 2006 - 12:21 am UTC
 
 
Hi Tom,
my database had this wait spike on the top latch# wait report, i searched metalink and have not found useful information about the detail of this latch, could you give me some highlight about this latch, what is it used, what activities in applications can cause this latch? Or maybe you have URL of it somewhere?
thanks a lot! 
 
 
Best ways to reduce the soft parses
ravinder matte, February  09, 2006 - 1:07 pm UTC
 
 
hi tom,
I am almost get out oh the hard parses. But i still lot of soft parses.
What would you recommend to start my war on the soft parses? 
 
February  10, 2006 - 11:24 am UTC 
 
a pow-wow with the developers.
They are the only ones that can reduce them.
Moving all sql out of the client into stored procedures is a good first start.  PLSQL caches SQL transparently.  So, if the application has a transaction that takes 5 sql statements - they are probably parsing 5 statements, executing 5 statements every time, over and over and over and over and over.
Move those 5 into a stored procedure, now the application has 1 statement "begin procedure(?,?,?...); end;".
When they call that the first time, Oracle will parse the 5 sql's
When they call that the second time in that session, we just execute them again, no parse.
All the coder has to do now is realize "I only have to parse the begin... end; statement ONCE.
Now you have minimized parsing.
Or, statement caching via the connection pool (Oracle connection pool in java permits this)
Or, </code>  
http://www.oracle.com/technology/products/oracle9i/daily/jun24.html  <code> 
 
 
Dave, February  16, 2006 - 11:56 am UTC
 
 
Hi Tom, confused over the output I am getting from the original script
SQL> select sql_text_wo_constants, count(*)
  from t1
 group by sql_text_wo_constants
having count(*) > 100
 order by 2
SQL_TEXT_WO_CONSTANTS
------------------------------------------------------------------------------------------------------------------------------
  COUNT(*)
----------
GRANT SELECT,INSERT
       226
TRUNCATE TABLE SYS.ORA_TEMP_@_DS_@
       251
But when I try to see what that tanle is..
SQL> select object_name from dba_objects where object_name like 'ORA_TE%';
no rows selected
Do you happen to know what that ORA_TEMP_@_DS_@ is?
It is also in a few other queries which come up as not using binds
 
 
 
February  17, 2006 - 1:11 pm UTC 
 
well, those are DDL and DDL cannot "bind" (you regularly grant 266 times?? or was this after an install or something?)
we sometimes have recursive sql that generates temporary tables (eg: I know flashback table does), but I'm not immediately familar with that exact name. 
 
 
 
Library cache lock problem
Deba, February  22, 2006 - 1:04 pm UTC
 
 
Hi,
I did not find any better related thread for posting my question, that's why I am posting here.
We are facing library cache lock very frequently. We have used the following sqlto track which user is waiting on which object due to library cache lock or pin.
SELECT /*+ ordered */ w1.sid  waiting_session,  h1.sid  holding_session,
w.kgllktype lock_or_pin,
w.kgllkhdl address,     DECODE(h.kgllkmod,  0, 'None', 1, 'Null', 2, 'Share', 3,
 'Exclusive',      'Unknown') mode_held,
        DECODE(w.kgllkreq,  0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',
   'Unknown') mode_requested,h1.sql_hash_value  ,lock_id1 object_waited_on
    FROM dba_kgllock w, dba_kgllock h, v$session w1, v$session h1 , dba_lock_internal dl
    WHERE   (((h.kgllkmod != 0) AND (h.kgllkmod != 1)      AND ((h.kgllkreq = 0)
 OR (h.kgllkreq = 1)))
     AND      (((w.kgllkmod = 0) OR (w.kgllkmod= 1))      AND ((w.kgllkreq != 0)
 AND (w.kgllkreq != 1))))
     AND  w.kgllktype    =  h.kgllktype   AND  w.kgllkhdl        =  h.kgllkhdl
AND  w.kgllkuse=w1.saddr   AND  h.kgllkuse=h1.saddr
and dl.mode_requested<>'None'
and dl.mode_requested<>dl.mode_held
and w1.sid=dl.SESSION_ID
WAIT_SES HOLD_SES    LOCK_OR_PIN    ADDRESS     MODE_HELD    MODE_REQUESTED    SQL_HASH_VALUE    OBJECT_WAITED_ON
110         80            Lock        E54B622C Exclusive    Share            1057805097        UPMARKET_EI_MV
112         110        Lock        E56289D8 Share        Exclusive        4103562029        SOLD_INFL_COMP_CPT_MV
76         110        Lock        E857A16C Share        Exclusive        4103562029        FACT_FORECAST_SUMMARY_MV
76         52            Lock        E857A16C Share        Exclusive        2349705177        FACT_FORECAST_SUMMARY_MV
52         80            Lock        E54B622C Exclusive    Share            1057805097        UPMARKET_EI_MV
In the above output you can see that session 110 is holding share lock on two different MVIEWS at same time - one is FACT_FORECAST_SUMMARY_MV and another one is SOLD_INFL_COMP_CPT_MV. This is not clear to me . At the same
time how a session can held share lock on two different mviews ? Under what circumstances share lock on mview is used? Can programmer cotrol this lock manually  means can we keep this type of lock for sometimes or it is maintained by Orcale only and programmer does not have any control over this lock? Could you explain this shared lock on MVIEWS with example please ? How share lock on two diffrent MVIEWS at same time by single session get maintained by oracle? please give one example.
Thanks
Deba 
 
February  22, 2006 - 2:06 pm UTC 
 
are they in a refresh group together?
But yes, a program can easily lock multiple objects.
More information - the sessions, what are they doing, are they your programs or are they refresh jobs - what? 
 
 
 
Dave from UK's question
Philip Douglass, February  22, 2006 - 5:49 pm UTC
 
 
Dave from UK:
Are you using DBMS_STATS? I regularly see ORA_TEMP_@_DS_@ tables in my v$session_longops table when I run dbms_stats.gather_table_stats on large tables. 
 
 
Library cache lock problem  
Deba, February  23, 2006 - 6:06 am UTC
 
 
Hi, 
We refresh soem views at specific time interval using dbms_mviews.refresh. The mviews are not in refresh group. This is ongoing process. Some process capture data from OLTP ( CDC is configured ) thruogh database link, some process refresh mviews and some process calculate data and store them in different tables.
What we want to know when shar lock on mview gets generated ? Accordingly we can see the codes. Is there any issue while refreshing mviews. We tried to simulate this but failed. We don't know when share lock on mview gets generated.
Thanks
Deba 
 
February  23, 2006 - 8:18 am UTC 
 
How did you determine this to be a problem.
what "codes"? 
 
 
 
Library cache lock problem
deba, February  23, 2006 - 1:49 pm UTC
 
 
Hi,
The use of MVIEWS is all follows :
1) We refresh them at regular intervals
2) We select data from MVIEWS ( either using SELECT only or INSER INTO ... SELECT ... )
We can see lot of sessions are waiting on 2 or 3 sessions. These 2 or 3 sessions generally held shared lock on MVIEWS. Now I want to know when Oracle acquire share lock on MVIEWS. When we select data there should not be any share lock on MVIEW. There will be exclusive lock on MVIEWS when those get refreshed. So when blocking sessions held share lock on MVIEWS then it means that there is no refresh for MVIEWS. It puzled me why session held share lock on MVIEWS though it is not doing any refresh.So I want to know 
a) Under which circumstances share lock on MVIEWS get generated ? Is it possible to simulate ? If so then how ?
b) Some MVIEWS are based on other other MVIEWS also.Under any situations share lock on MVIEWS can be generated due to change in underlying MVIEWS or underlying tables ? Changes mean any changes ( either data or structure ).
Deba  
 
February  23, 2006 - 7:11 pm UTC 
 
but the shared lock will not prevent others from reading - so back to square one.
are these sessions accidently modifying the mview themself?
you always have the lock table command. 
 
 
 
Library cache lock problem
deba, February  27, 2006 - 8:52 am UTC
 
 
Hi,
There should be not be any share lock on MVIEW if I read from any MVIEW. Could you tell me when share lock on MVIEW generates ? 
 
 
library cache lock,
A reader, March     29, 2006 - 1:57 pm UTC
 
 
What should we look (and also where should we look) when there is a library cache lock when running a dbms_stats package on a half a million row table?
The table is a non-partitioned and has one primary key on that.  The library cache lock happens even if I use "analyze table" instead of DBMS_STATS.  Also, when I tried to change the degree value by using alter table, again it hangs with the same wait event.
When it is waiting on library cache lock, even a simple select statement on that table just hangs.
We have found out the work around by creating a temp table, create a primary key on that, drop the existing table and rename the temp table back to the existing one.  The analyze or dbms_stats on that temp table worked just fine.
The database is 10.0.1 and running on a 5 node RAC.
Interestingly, the library cache happens on only that particular table and when I tried analyzing other big tables it just analyzes fine.  
 
 
March     29, 2006 - 2:24 pm UTC 
 
please work this one via support - doesn't sound "right", it is not normal. 
 
 
 
Could you Please Explain the difference in DIfferent Library Cache Latch
Raj, April     21, 2006 - 8:59 am UTC
 
 
Hi Tom,
Could you please explain the difference between the following latch.
LATCH.library cache pin
LATCH.shared pool
LATCH.library cache pin allocation
LATCH.library cache            
It is very confusing when each type of latch is acquired.
Thanks and Regards,
Raj 
 
April     21, 2006 - 9:15 am UTC 
 
what we really need to know is what gets them - parsing, it is all about parsing.
reduce parsing, reduce getting them.  
you are free to search metalink to see the notes on them. 
 
 
 
Library cache lock
Ray, April     25, 2006 - 2:14 pm UTC
 
 
This has been an intersestion thread to me. I would like to share a problem which I encountered recently
We have a a view which does quite a number of PL/SQL function calls (should not do. trying to get rid of the function calls). A couple of function calls uses execute immediate statements. These functions are quite bulky in nature. The packages containing these functions are bulky themselves
Whenever a SQL is issued against this view it holds the library cache lock for a long time. I have learned from Steve Adams' site that ' a library cache lock is also held when a referenced object is not pinned'. 
My questions are:
1. Does a PL/SQL call from a SQL statement result in library cache lock owing to context switch?
2.Could it be that the package (in chunks) gets paged out and the session holds the lock and waits for the package to be pinned again?
3. Is it the 'execute immediate' statements causing the problem? 
4. Is 'execute immediate' statement condidered a DML (even if it does no DML operation)? If so, then it might break the  exisisting parse locks (again from Steve Adams)(occuring many times over for as many number of rows) requiring a reparse and hence the lock?
Yor views and clarification would resolve my state of confusion. Apologies, if I have misinterpreted Steve Adams in appropriately and used it in the wrong context of my problem. 
Thanks in advance for your valuable time and your unconditional service to the Oracle community.
Regards
Ray
 
 
 
Very useful
Vinayak Pai, April     26, 2006 - 5:27 am UTC
 
 
The code provided to check if there is a Lbrary cache latch contention was very useful. 
 
 
session_cahced_cursors
A reader, May       03, 2006 - 12:08 pm UTC
 
 
Is this paramater has any effect on the library cache latch contention?
If yes, Could you please explain me how this effects?
Thanks 
 
 
Error on running Lbrary cache latch contention script
Anne Joseph, August    09, 2006 - 4:30 pm UTC
 
 
Hi Tom,
I'm trying to run your script to determine whether bind variables are being used or not, and I get ORA-01401. We are running 11i , rdbms 9.2.0.6 , Red Hat Linuz 2.1.  Could you please help me out.  Thanks.
SQL> create table t1 as select sql_text from v$sqlarea;
Table created.
SQL> 
SQL> alter table t1 add sql_text_wo_constants varchar2(1000);
Table altered.
SQL> create or replace function 
  2  remove_constants( p_query in varchar2 ) return varchar2
  3  as
  4      l_query long;
  5      l_char  varchar2(1);
  6      l_in_quotes boolean default FALSE;
  7  begin
  8      for i in 1 .. length( p_query )
  9      loop
 10          l_char := substr(p_query,i,1);
 11          if ( l_char = '''' and l_in_quotes )
 12          then
 13              l_in_quotes := FALSE;
 14          elsif ( l_char = '''' and NOT l_in_quotes )
 15          then
 16              l_in_quotes := TRUE;
 17              l_query := l_query || '''#';
 18          end if;
 19          if ( NOT l_in_quotes ) then
 20              l_query := l_query || l_char;
 21          end if;
 22      end loop;
 23      l_query := translate( l_query, '0123456789', '@@@@@@@@@@' );
 24      for i in 0 .. 8 loop
 25          l_query := replace( l_query, lpad('@',10-i,'@'), '@' );
 26          l_query := replace( l_query, lpad(' ',10-i,' '), ' ' );
 27      end loop;
 28      return upper(l_query);
 29  end;
 30  /
Function created.
SQL> update t1 set sql_text_wo_constants = remove_constants(sql_text);
update t1 set sql_text_wo_constants = remove_constants(sql_text)
       *
ERROR at line 1:
ORA-01401: inserted value too large for column
Thanks. 
 
 
August    09, 2006 - 5:12 pm UTC 
 
make the column we added wider then.
 
 
 
 
Why column not large enough
Anne Joseph, August    10, 2006 - 9:42 am UTC
 
 
Thanks Tom. I increased it and it worked of course! But I'm curious why I had to increase it. I had read your explanation of the code : "My remove constants turns any character string literal into '#' and any number into @" - so after the translation the length of t1.sql_text_wo_constants and v$sqlarea.sql_text should be the same, right ?  Obviously there is something I am missing here - could you please help explain.
The script revealed :
SQL_TEXT_WO_CONSTANTS
------------------------------
  COUNT(*)
----------
SAVEPOINT ORACLE_SVPT_@
       197
SQL> select sql_text from v$sql
  2  where upper(sql_text) like 'SAVEPOINT ORACLE_SVPT_%';
SQL_TEXT
------------------------------------------------------------------
SAVEPOINT ORACLE_SVPT_111
SAVEPOINT ORACLE_SVPT_34
SAVEPOINT ORACLE_SVPT_198
SAVEPOINT ORACLE_SVPT_125
SAVEPOINT ORACLE_SVPT_189
SAVEPOINT ORACLE_SVPT_200
SAVEPOINT ORACLE_SVPT_136
........
This goes on as SAVEPOINT ORACLE_SVPT_<nnnnn>....  197 rows.
From reading your excellent info on binding, I think the reason this is coming up is because this must be a dynamic statement where the savepoint name is NOT a bind parameter. Please correct me if I am wrong. 
This is a 11i application, so I am not sure if I can "fix" the app - is there any other way to fix this ?
As always thanks so much for the wealth of info on binding - great eye opener! 
 
 
August    10, 2006 - 9:49 am UTC 
 
savepoint name cannot be bound, corret.  But in this case - there will be a fixed number of savepoints won't there - you cannot change the name of the savepoint (it would radically affect the behavior of the application!!!!!)
If a query has:
where x = ''
I will turn that into 
where x = '#'
that is, I might make a string LONGER than it was - and that could result in a string longer than the 1000 characters that was input. 
 
 
 
Why column not large enough
Anne Joseph, August    10, 2006 - 2:11 pm UTC
 
 
Yes, I see now - I hadn't thought of the empty string, and, neither did I think about the effects of changing the name of the savepoint!! Thanks for the prompt response!
 
 
 
How about users_executing?
Raghu, August    22, 2006 - 2:20 pm UTC
 
 
Instead of 
"create table t1 as select sql_text from v$sqlarea;" do you think we should have
"create table t1 as select sql_text from v$sqlarea where users_executing > 0;" ?
SQLs in v$sqlarea not currently executing should have no impact on the performance at this time right? 
 
 
August    27, 2006 - 3:08 pm UTC 
 
why?  you are actually not expecting the sql of interest to be currently being executed!  It has literals in it, the supposition is it is executed once and never again.
maybe "users_executing = 0", but not > 0 for sure!!!
No, it should be just as I did it. 
 
 
 
Shared_pool_size is Zero
oracleo, August    27, 2006 - 9:42 am UTC
 
 
The following is the output of v$parameter.
  108 shared_pool_size                    6 0
  110 large_pool_size                     6 0
  112 java_pool_size                      6 0
  114 streams_pool_size                   6 0
  116 shared_pool_reserved_size           6 7759462
  404 buffer_pool_keep                    2
In one of the databases, it was revelation, that shared pool size is 0. according to me it could cause lots of contention in library cache. 
pls advice 
 
August    27, 2006 - 9:13 pm UTC 
 
or you could be using automatic sga sizing....
ops$tkyte%ORA10GR2> show parameter pool
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_keep                     string
buffer_pool_recycle                  string
global_context_pool_size             string
java_pool_size                       big integer 0
large_pool_size                      big integer 0
olap_page_pool_size                  big integer 0
shared_pool_reserved_size            big integer 7969177
shared_pool_size                     big integer 0
streams_pool_size                    big integer 0
ops$tkyte%ORA10GR2> show parameter sga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 580M
sga_target                           big integer 580M
ops$tkyte%ORA10GR2>
I have a 580m sga, Oracle is figuring out how much to put into each pool and can/will change its mind over time. 
 
 
 
 
forgot to mention
oracleo, August    27, 2006 - 9:52 am UTC
 
 
version is 10Gr2 on linux Redhat 
 
 
Hit ratio very high
Richard, September 19, 2006 - 4:06 pm UTC
 
 
 Tom,
   I recently read a paper by Cary Millsap about how works the Buffer Cache and how a Hr > 95 (more or less) could point a bad sql and a very cpu usage. It is a very good article. Then I read that Hit ratios very very high is not always good. Mi question is why is too bad a very high hit ratio in the Shared Pool? In Buffer Cache now I can understand why but not in the Shared Pool. Could you please clarify me this point?
   Thanks in advance Tom. 
 
September 20, 2006 - 2:36 pm UTC 
 
where did you read it about the shared pool? 
 
 
 
Hit Ratio
A reader, September 21, 2006 - 9:45 am UTC
 
 
  Sorry, I would refer to the library cache. When Cary Millsap talk about that hit ratios, in general, are not useful to lead a tuning, the case of study was the Buffer Cache. I don´t know if in any other areas like Shared Pool -> Library Cache, PGA ... etc this issue is similar, i.e. imagine mi H.r. in my library cache is close to 100%. Could I assert that there is no problem with my library cache?
  Thank you Tom. 
 
September 22, 2006 - 2:06 am UTC 
 
his point is - that the GOAL is NOT to get some ratio to 100%.  That is not the goal.
You could have a ratio for anything of say "50%" and that might well be perfectly acceptable.  
If your library hit ratio is near 100%, you could have a serious problem.  You might have code that looks like this:
for i in 1 .. 10000000
loop
    parse "insert into t values ( :x )"
    bind i to :x
    execute statement
    close statement
end loop
that is one way to ensure a really good library cache hit - parse way too often, this piece of code:
parse "insert into t values ( :x )"
for i in 1 .. 10000000
loop
    bind i to :x
    execute statement
end loop
close statement
may well cause your "hit ratio" to decrease - but your overall performance would be so much better. 
 
 
 
Hit ratio
Richard, September 22, 2006 - 8:47 am UTC
 
 
 Thank you Tom. Your example is simple and very good. As always. 
 
 
related ORA-4031 error
Aj Joshi, November  11, 2006 - 10:08 pm UTC
 
 
Tom,
   When memory is needed oracle allocates from shared pool. If it does not find it then it removes unused sql. LRU 
Question : Apart from packages/procedures PINNED/KEPT in memory what else cannot be removed when memory is needed? 
 I am not sure about session memory as decided by param session_cached_cursors can be removed. 
 
About pinning objects : It was for oracle7 and it was supposed to improve with 8i/9i since memory in pieces can be allocated. Something like if total memory needed is 40K then it could get 4 chunks of 10K that are not contiguous and then satisfy the request. Correct me if I am wrong. So the question is in that case why do we keep getting this error in 8i and even on 9i. Must be some explanation. I think there is a minimum allocation it does. For example if I give a short sql like : 'select * from dual' which does not need much memory then I think it still allocates a bigger minimum amount. How much is this minimum amount of memory. Is it 1K. Is it determined by some params. 
Since memory used by old sql which is not used can be reused. LRU algorithm or whatever : And at any given time a small number of sql in memory is being actively used : So it can always remove the old sql and use the memory : so less chance of ORA-4031 unless there are lot of active processes. However we have seen serious ORA-4031 errors even in case of very less active processes. Sometimes needing bounce.  
Other than PINNED objects and session_cached_cursors I think shared pool sql can be removed and yet we get this ORA-4031 error.We do see a lot of inactive processes like over 400 inactive and very less active like less than 30. So are the inactive ones holding on to session_cached_cursors. No, there is no way to reduce the inactive processes. 
 
 
November  12, 2006 - 10:19 am UTC 
 
answer: any freeable memory, each component of Oracle when allocating from the shared pool will say whether this has to stay or not.  Way too many things to go into any sort of detail on.
Session memory is in the UGA and is not touchable except by the session really (normally, the session memory is actually in a dedicated server - way removed from the SGA all together)
Pinning was sort of introduced to help with shared server (known as MTS - multi-threaded server way back when).  It would allocate the UGA out of the shared pool and as this was not managed in an LRU (it was explictly allocated/deallocated) and tended to use lots of different sizes and shapes, you would end up with a shared pool that had lots of unfreeable bits in it - breaking it up entirely.  So, enter the --- large pool, remove the shared server memory allocations from the shared pool.
 
 
 
 
big parse, samll parse
John, November  14, 2006 - 12:31 pm UTC
 
 
Tom,
1. Which is worse, parsing a 5000-line SQL 2 times or parsing a 1 line SQL 500 times?
2. To parse 2 5000-line SQL, is it posible to say which is worse than the other? What makes one worse than the other in terms of negatively impacting the system?
John 
 
November  15, 2006 - 6:41 am UTC 
 
eh?  how long is a piece of string.
the only sensible answer is:
it depends. 
 
 
 
Non Usage of Bind Variables
Shivdeep Modi, November  15, 2006 - 1:00 pm UTC
 
 
A handy script and an interesting thread 
 
 
Just look at that...
Reader, November  15, 2006 - 9:06 pm UTC
 
 
Just came other this on metalink forum:
BEGIN PKG_NAME(:DBP_AABEG,:DBP_AABEH,:DBP_AABEI); END;
BEGIN PKG_NAME(:DBP_AABGQ,:DBP_AABGR,:DBP_AABGS); END;
BEGIN PKG_NAME(:DBP_AABMJ,:DBP_AABMK,:DBP_AABML); END; 
So - as you can see, just using bind variables is sometimes makes no difference from not using them at all :) 
 
November  16, 2006 - 3:03 pm UTC 
 
eh?  you make zero sense here. 
 
 
 
Reader
Reader, November  16, 2006 - 8:10 pm UTC
 
 
eh-heh, but you'll get same hard parsing on every statement regardless...
my point was - "just use bind variables" sometimes doesn't solve hard parsing issues :) 
 
November  17, 2006 - 3:19 am UTC 
 
yes it does, it allows you to make the number of hard parses as small as possible - which is the only way to "solve" a hard parse issue.
there are many reasons why "you bind but it is not shareable" - from optimizer related settings, to bind mismatches, to nls settings, to security settings, to .....
 
 
 
 
ok
Reader, November  17, 2006 - 4:48 am UTC
 
 
"there are many reasons why "you bind but it is not shareable" - from optimizer related settings, to bind mismatches, to nls settings, to security settings, to ....."
ok, i suppose you was not looking at my previous review...
here:
BEGIN PKG_NAME(:DBP_AABEG,:DBP_AABEH,:DBP_AABEI); END;
BEGIN PKG_NAME(:DBP_AABGQ,:DBP_AABGR,:DBP_AABGS); END;
BEGIN PKG_NAME(:DBP_AABMJ,:DBP_AABMK,:DBP_AABML); END; 
they have *unique* bind variable names for each statement - seems that they just auto-generate them.
no matter what - you'll get hard parse each time here. That was my point. 
 
November  17, 2006 - 8:03 am UTC 
 
ouch, I cannot believe they did that - didn't even notice.
 
 
 
 
Alexander the ok, November  17, 2006 - 11:47 am UTC
 
 
The bind variable names matter?  I thought you could call your bind variable anything and the difference was just that you were using one vs no binds. 
 
November  19, 2006 - 4:08 pm UTC 
 
the sql matching is, has been, will be by "text match"
unless you have the same text (including "case of text", "white space", etc) - they are different. 
 
 
 
Proof...
J. Laurindo Chiappa, November  17, 2006 - 1:10 pm UTC
 
 
Alexander, the proof is very easy : remember, Oracle SQL processing IS based on text-recognizing, and different bind variables IMPLIES in differente texts, thus DIFFERENT hashes... See, in the SAME machine, SAME user, same everything :
scott@BDDEV:SQL>variable x number;
scott@BDDEV:SQL>variable y number;
scott@BDDEV:SQL>select /*+ TEST_01 */ loc, deptno, deptno + 10 result from dept where deptno = :x;
scott@BDDEV:SQL>select /*+ TEST_01 */ loc, deptno, deptno + 10 result from dept where deptno = :y;
system@BDDEV:SQL>select * from v$sqlarea where sql_text like 'select /*+ TEST_0%';
SQL_TEXT
------------------------------------------------------------      SHARABLE_MEM     PERSISTENT_MEM        RUNTIME_MEM              SORTS      VERSION_COUNT    LOADED_VERSIONS      OPEN_VERSIONS      USERS_OPENING            FETCHES         EXECUTIONS    USERS_EXECUTING              LOADS FIRST_LOAD_TIME          INVALIDATIONS        PARSE_CALLS         DISK_READS        BUFFER_GETS     ROWS_PROCESSED       COMMAND_TYPE OPTIMIZER_MODE               PARSING_USER_ID  PARSING_SCHEMA_ID      KEPT_VERSIONS ADDRESS                  HASH_VALUE MODULE                                                                  MODULE_HASH ACTION                                                                  ACTION_HASH SERIALIZABLE_ABORTS           CPU_TIME       ELAPSED_TIME I        CHILD_LATCH
------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------- ------------------ ------------------ ---------------------
select /*+ TEST_01 */ loc, deptno, deptno + 10 result from dept where deptno = :x
             17187               1208               2464                  0                  1                  1                  0                  0                  1                  1                  0                  1 2006-11-17/14:51:16                  0                  1                  0                  0                  0                  3 CHOOSE                                    22                 22                  0 C000000079996BC0         3582669877 SQL*Plus                                                                 -625018272                                                                          -265190056                   0                  0                925 N                  2
select /*+ TEST_01 */ loc, deptno, deptno + 10 result from dept where deptno = :y
             17595               1208               2464                  0                  1                  1                  1                  1                  1                  1                  0                  1 2006-11-17/14:51:16                  0                  1                  0                  0                  0                  3 CHOOSE                                    22                 22                  0 C000000079AA02E8         4254623821 SQL*Plus                                                                 -625018272                                                                          -265190056                   0                  0                889 N                  2
==> See ? Two DIFFERENT statements, two hard parses, only due DIFFERENT bind names...
 Regards,
 
   Chiappa 
 
 
 
remove_constants and bind variables
Tony Baker, November  21, 2006 - 10:33 am UTC
 
 
Thanks for all the information provided.
I suspect that the application that is running against the databases that I look after is not using bind variables.
I have tried running your script remove_constants but I get
the following errors 
Function created.
update t1 set sql_text_wo_constants = remove_constants(sql_text)
                                      *
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SYSTEM.REMOVE_CONSTANTS", line 10
SQL_TEXT_WO_CONSTANTS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      COUNT(*)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               2798
1 row selected.
I have looked in the table T1, below is an example of the SQL returned
select u.EMP_NO, g.GROUP_ID,g.ACCESS_OWN_DATA,g.CONDITION_NAME,g.COND_SUCCESS_ACTION,g.COND_FAILURE_ACTION, g.REPORTEE_SEC, u.USER_PWD, u.SECURITY_OFFICER, u.ADMIN_OPTIONS, u.MODULE_OPTIONS from PS_USERS u, PS_GROUPS g where u.USER_ID='LWPSE9' and u.GROUP_ID=g.GROUP_ID
select u.EMP_NO, g.GROUP_ID,g.ACCESS_OWN_DATA,g.CONDITION_NAME,g.COND_SUCCESS_ACTION,g.COND_FAILURE_ACTION, g.REPORTEE_SEC, u.USER_PWD, u.SECURITY_OFFICER, u.ADMIN_OPTIONS, u.MODULE_OPTIONS from PS_USERS u, PS_GROUPS g where u.USER_ID='PACE04' and u.GROUP_ID=g.GROUP_ID
select u.EMP_NO, g.GROUP_ID,g.ACCESS_OWN_DATA,g.CONDITION_NAME,g.COND_SUCCESS_ACTION,g.COND_FAILURE_ACTION, g.REPORTEE_SEC, u.USER_PWD, u.SECURITY_OFFICER, u.ADMIN_OPTIONS, u.MODULE_OPTIONS from PS_USERS u, PS_GROUPS g where u.USER_ID='PACE17' and u.GROUP_ID=g.GROUP_ID
The SQL is identical apart from the following
 
u.USER_ID='LWPSE9'
u.USER_ID='PACE17'
u.USER_ID='PACE04'
If the application was using bind variables would the results in the table T1 show a single entry for this query instead of three and should I expect to see
u.USER_ID='LWPSE9'
u.USER_ID='PACE17'
u.USER_ID='PACE04'
replaced with something like
u.USER_ID=:user 
 
November  22, 2006 - 3:39 pm UTC 
 
make buffer bigger. 
 
 
 
gethitratio
A reader, December  07, 2006 - 6:26 pm UTC
 
 
Tom, 
The gethitratios in library cache are extremely low.. Instead of being around 90% they are less than 1%. Please shortly explain what is the main reason. Thanks.
NAMESPACE    GETHITRATIO
SQL AREA    0.96008153
TABLE/PROCEDURE    0.998642242
BODY    0.998955199
TRIGGER    0.999912234
INDEX    0.46969697
CLUSTER    0.993840985
OBJECT    1
PIPE    1
JAVA SOURCE    1
JAVA RESOURCE    1
JAVA DATA    1
 
 
December  08, 2006 - 7:25 am UTC 
 
multiply by 100 and you'll be happier perhaps. 
 
 
 
A reader, December  08, 2006 - 10:11 am UTC
 
 
Tom,
When I multiply by 100, all other gethitratios are ok but the index is 46.96%. Is that an indication latche contention is occuring when indexes are used? Any means to correct it? The schema has tables with unindexed foreign keys. On the average, a deadlock occurs once every month in the database. Thanks ... 
 
December  09, 2006 - 12:28 pm UTC 
 
no, it does not.
bet if you look at the underlying numbers that make the ratio, you'll find them to be of no consequence (eg: small)
so look into the numbers behind the numbers. 
 
 
 
Not able to select on table due to library cache
A reader, May       03, 2007 - 12:18 am UTC
 
 
Tom,
 Last week there was Library cache lock on a table because of which we were not able to even select that table.We thought that the table was dropped by some one but after careful investigation we found it as library cache lock.
1)I am wondering about How can library cache lock will disable select/describe on table?
2)What all possible reasons to get library cache lock on table and disable readonly also on that table
I used the following steps to find the SID which is causing block but interestingly this user has only read only access on that table.It can not DML/DDL on that table
step1:
select /*+ ordered use_nl(lob pn ses) */
  decode(lob.kglobtyp, 0, 'NEXT OBJECT', 1, 'INDEX', 2, 'TABLE', 3, 'CLUSTER',
  4, 'VIEW', 5, 'SYNONYM', 6, 'SEQUENCE',
  7, 'PROCEDURE', 8, 'FUNCTION', 9, 'PACKAGE',
  11, 'PACKAGE BODY', 12, 'TRIGGER',
  13, 'TYPE', 14, 'TYPE BODY',
  19, 'TABLE PARTITION', 20, 'INDEX PARTITION', 21, 'LOB',
  22, 'LIBRARY', 23, 'DIRECTORY', 24, 'QUEUE',
  28, 'JAVA SOURCE', 29, 'JAVA CLASS', 30, 'JAVA RESOURCE',
  32, 'INDEXTYPE', 33, 'OPERATOR',
  34, 'TABLE SUBPARTITION', 35, 'INDEX SUBPARTITION',
  40, 'LOB PARTITION', 41, 'LOB SUBPARTITION',
  42, 'MATERIALIZED VIEW',
  43, 'DIMENSION',
  44, 'CONTEXT', 46, 'RULE SET', 47, 'RESOURCE PLAN',
  48, 'CONSUMER GROUP',
  51, 'SUBSCRIPTION', 52, 'LOCATION',
  55, 'XML SCHEMA', 56, 'JAVA DATA',
  57, 'SECURITY PROFILE', 59, 'RULE',
  62, 'EVALUATION CONTEXT',
  'UNDEFINED') object_type,
  lob.kglnaobj object_name,
  pn.kglpnmod lock_mode_held,
  pn.kglpnreq lock_mode_requested,
  ses.sid,
  ses.serial#,
  ses.username
  from v$session_wait vsw,
  x$kglob lob,
  x$kglpn pn,
  v$session ses
  where vsw.event = 'library cache lock'
  and vsw.p1raw = lob.kglhdadr
  and lob.kglhdadr = pn.kglpnhdl
  and pn.kglpnmod != 0
  and pn.kglpnuse = ses.saddr
Step 2:
  select spid as thread, sid, osuser, s.program
    from sys.v_$process p, sys.v_$session s
   where p.addr = s.paddr
   and s.sid=<sid>
 Step 3:
  kill -9 <pid>
Thanks
 
 
library cache lock 
Sean, July      31, 2007 - 2:44 pm UTC
 
 
Tom,
i was asked to improve the performance on the materialized-views -MVs build. the MVs have rebuilt every night (do not ask why). they do the one after other. i thought if build them in parallel would be much fast. so i have been testing the parallel MVs build. and found most of the build sessions wait on "library cache lock". i used query to find what are the objs being locked:
select oracle_username, os_user_name, session_id, process,
       locked_mode, o.owner, o.object_type, o.object_name
  from sys.dba_objects o,
       v$locked_object l
 where l.object_id = o.object_id
 order by o.owner, o.object_name, session_id
they are the sys owned:
SNAP_LOADERTIME$
SNAP_LOGDEP$
SUMAGG$
SUMDELTA$
MLOG$
OBJ$
SNAP$
SUMINLINE$
SUMJOIN$
 SUMKEY$
SUMPARTLOG$
SUMPRED$
What could MVs build parallel avoid the library cache lock?
Thanks In Avance. 
August    02, 2007 - 10:11 am UTC 
 
I will ask why.  
define what you mean by "rebuilt", describe the process please 
 
 
Profile of the SQL statements in cache
Sandro, October   02, 2007 - 5:15 pm UTC
 
 
Hi Tom,
I have find this script at  
http://www.dba-village.com/village/dvp_scripts.ScriptDetails?ScriptIdA=1842  link.
-------------------------- begin --------------------------
ttitle "Count of executions, grouped by minutes cached." 
break on exec skip 2
select
       exec ,
       substr(Min_Cached,5) Min_Cached,
       COUNT(*),
       ROUND(AVG(Executions),2) Avg_Exec,
       sum(executions) Executions,
       min(executions) Min_Exec,
       max(executions) Max_Exec,
       round(sum(OPTIMIZER_COST),0) Cost
 ,substr(to_char(100 * ratio_to_report(sum(OPTIMIZER_COST)) over (), '999.00'), 2) || '%'  pct_Cost
  from (
        select decode(executions,0,0,1,1,2,2) exec,
               DECODE(Min_Cached,
               0,' 1) 00-01min',
               1,' 2) 01-02min',
               2,' 2) 01-02min',
               DECODE(SIGN(Min_Cached-    6),-1,' 3) 03-05min',
               DECODE(SIGN(Min_Cached-   16),-1,' 4) 06-15min',
               DECODE(SIGN(Min_Cached-   31),-1,' 5) 16-30min',
               DECODE(SIGN(Min_Cached-   61),-1,' 6) 31-60min',
               DECODE(SIGN(Min_Cached-  121),-1,' 7)  1- 2hr',
               DECODE(SIGN(Min_Cached-  180),-1,' 8)   - 3hr',
               DECODE(SIGN(Min_Cached-  240),-1,' 9)   - 4hr',
               DECODE(SIGN(Min_Cached-12*60),-1,'10)   -12hr',
                    '11) 12hr+  '))))))))) Min_Cached,
               Executions,OPTIMIZER_COST
          from (
               select ROUND((SysDate-
                       TO_DATE(First_Load_Time,
                       'yyyy-mm-dd/hh24:mi:ss'))*24*60) Min_Cached,
                      Executions,OPTIMIZER_COST
                 from V$SQL
                where Parsing_User_ID != 0
                and executions>0
               )
        )
group by exec,Min_Cached;
-------------------------- end --------------------------
Scope of this sql script is to obtain Statistical information about the number of executions of a statements, and time in cache, to identify the profile of the statements by the applications on a database.
It is a good start to identify not using bind s variable? 
October   05, 2007 - 11:03 am UTC 
 
how does this help you find sql statements not using a bind?
I gave you an approach above. 
 
 
Cursor sharing
JAM, October   05, 2007 - 6:27 pm UTC
 
 
Tom,
Just wondering: Does the following statement from a 3rd party vendor make you laugh or cry?
XXXX does not use bind variables because of the unique way in which users can build their own queries within the application. 
Seriously, the unique way the vendor refers to is a search screen with about 50 columns that users can plug-in various variables to one or more column. (The table by the way is about 300 columns, 40M rows)
Haven't provided any specifics because I'm just curious about your general feeling of the vendors statement.  In your experience have you found applications with legitimate reasons for not using bind? 
 
Track Hard Parse Statements Over Time
Robert, April     23, 2008 - 6:43 pm UTC
 
 
Tom,
I have been using your query/method at the top of the page with great success.
I have shown some of the Developers a snapshot/summary of library cache of all similar statements not using bind variables where count(*) > 100 and it seems to have gotten their attention.
Now we want to have an ongoing report that shows offending SQL ranked in order of severity ('duplicate' statements).
Here is my question: Your script takes a snapshot of a single moment in time but V$SQL can change from hour to hour... and I want to get a summary of ALL major offenders for an entire week. How can I collect those hard parse statement stats/queries for an entire week?
What about creating a table with primary key of first_load_time, hash_value, and substr(sql_text), then every hour, say, take a snapshot of v$sql based on your query above... but capture ALL statements which match your criteria... the first_load_time would insure I didn't double up on sql that stayed in v$sql between snapshots.
Tben for the weekly report I can summarize them all up again with counts.
What do you think?
Thanks,
Robert. 
April     28, 2008 - 9:39 am UTC 
 
... Now we want to have an ongoing report that shows offending SQL ranked in order 
of severity ('duplicate' statements).
 ..
why - it only takes ONE occurrence of ONE bad sql statement to kill everything.
You cannot get what you want - the bad sql is coming and going so fast - that you are missing many sql statements likely in your hourly snapshots as it is.  (eg: the worst offender could appear to be the "least used one" just because your shared pool is flushing so often...)
Stick with you have and keep nailing them one by one till they are all gone.   
 
 
What about General/Summary Hard Parse Stats?
Robert, April     29, 2008 - 7:53 am UTC
 
 
Tom,
Thank you for the insight into my question on tracking hard parses.
What stats can I look at, either Statspack report, v$ stats, etc. that would indicate or suggest lots of hard parses going on at a given point, a given hour, etc.?
Thank you,
Robert. 
April     29, 2008 - 8:49 am UTC 
 
statspack - right at the top - shows this very clearly.
there is a total parse count, a hard parse count and a soft parse %
total parse count - shows if you are parsing like crazy (soft and hard parsing)
the total + hard parse count are used to generate a soft parse percentage (what percent of parses were SOFT vs HARD).  This number should pretty much be very high - above 99% in general.  One of the few few few ratios you can say "it should definitely be in this range".  
 
 
Robert, April     29, 2008 - 10:43 am UTC
 
 
 
 
Sam Mousleh, June      13, 2008 - 7:45 am UTC
 
 
Tom, I have ran the script you provided to find Lbrary cache latch contention. So as result I can see many queries with the count is high, example count for the last query is 2158, please look at the last section for the script results. And the hit ratio's from the statspack is very good:
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %:  100.00       Redo NoWait %:    100.00
            Buffer  Hit   %:   94.80    In-memory Sort %:    100.00
            Library Hit   %:   99.99        Soft Parse %:     99.70
         Execute to Parse %:   96.60         Latch Hit %:     99.58
Parse CPU to Parse Elapsd %:   92.98     % Non-Parse CPU:     99.63
I don't realy understand the purpose of it, in the statspack report I do see many latch sleeps:
Latch Activity for DB: SABO  Instance: SABO  Snaps: 28176 -28178
->"Get Requests", "Pct Get Miss" and "Avg Slps/Miss" are statistics for
  willing-to-wait latch get requests
->"NoWait Requests", "Pct NoWait Miss" are for no-wait latch get requests
->"Pct Misses" for both should be very close to 0.0
                                           Pct    Avg   Wait                 Pct
                              Get          Get   Slps   Time       NoWait NoWait
Latch                       Requests      Miss  /Miss    (s)     Requests   Miss
------------------------ -------------- ------ ------ ------ ------------ ------
Consistent RBA                  108,273    0.0             0            0
FAL request queue                     4    0.0             0            0
FIB s.o chain latch                 132    0.0             0            0
FOB s.o list latch                2,265    0.0             0            0
SQL memory manager latch              2    0.0             0        1,191    0.0
SQL memory manager worka      1,158,591    0.0    0.0      0            0
X$KSFQP                              28    0.0             0            0
active checkpoint queue          12,053    0.0    0.0      0            0
alert log latch                      14    0.0             0            0
archive control                     424    0.0             0            0
archive process latch                80    0.0             0            0
begin backup scn array                1    0.0             0            0
cache buffer handles          1,395,954    0.0    0.0      0            0
cache buffers chains        837,999,907    0.1    0.0      4   46,634,519    0.0
cache buffers lru chain         343,842    0.5    0.0      0   67,019,084    0.2
cas latch                    32,205,261    0.1    0.0      0            0
channel handle pool latc            217    0.0             0            0
channel operations paren          2,800    0.0             0            0
checkpoint queue latch        2,201,940    0.0    0.0      0       57,609    0.0
child cursor hash table          29,824    0.0             0            0
commit callback allocati         12,781    0.0             0            0
dictionary lookup                     9    0.0             0            0
dml lock allocation             493,698    0.0    0.0      0            0
dummy allocation                    195    0.0             0            0
enqueue hash chains             779,023    0.0    0.0      0            0
enqueues                        363,025    0.0    0.0      0            0
event group latch                    95    0.0             0            0
global tx hash mapping              292    0.0             0            0
hash table column usage             141    0.0             0    1,706,189    0.0
job_queue_processes para             59    0.0             0            0
ktm global data                      23    0.0             0            0
lgwr LWN SCN                    108,276    0.0    0.0      0            0
library cache                99,847,263    1.0    0.0     15       11,817    4.6
library cache load lock           1,542    0.0             0            0
library cache pin            91,085,186    0.2    0.0      2            0
library cache pin alloca      7,150,475    0.0    0.0      0            0
list of block allocation          4,247    0.0             0            0
loader state object free            194    0.0             0            0
longop free list parent           1,271    0.0             0           59    0.0
message pool operations              14    0.0             0            0
messages                        369,323    0.0    0.0      0            0
mostly latch-free SCN           491,595    0.3    0.0      0            0
multiblock read objects      18,762,943    0.1    0.0      0            0
ncodef allocation latch              58    0.0             0            0
object stats modificatio             12    0.0             0            0
post/wait queue                 202,484    0.0    0.0      0      105,514    0.0
process allocation                   95    0.0             0           95    0.0
process group creation              195    0.0             0            0
redo allocation                 957,456    0.0    0.0      0            0
redo copy                             0                    0      741,027    0.0
Latch Activity for DB: SABO  Instance: SABO  Snaps: 28176 -28178
->"Get Requests", "Pct Get Miss" and "Avg Slps/Miss" are statistics for
  willing-to-wait latch get requests
->"NoWait Requests", "Pct NoWait Miss" are for no-wait latch get requests
->"Pct Misses" for both should be very close to 0.0
                                           Pct    Avg   Wait                 Pct
                              Get          Get   Slps   Time       NoWait NoWait
Latch                       Requests      Miss  /Miss    (s)     Requests   Miss
------------------------ -------------- ------ ------ ------ ------------ ------
redo on-disk SCN                343,716    0.0             0            0
redo writing                    339,347    0.0    0.0      0            0
row cache enqueue latch      62,201,242    0.2    0.0      0            0
row cache objects            62,209,555    4.2    0.0      0          190    0.0
sequence cache                  101,827    0.0    0.0      0            0
session allocation              685,027    0.0    0.0      0            0
session idle bit              1,563,084    0.0    0.0      0            0
session switching                    58    0.0             0            0
session timer                     1,212    0.0             0            0
shared pool                  41,912,797    1.0    0.0      1            0
sim partition latch                   0                    0        3,138    0.0
simulator hash latch         33,381,090    0.0    0.0      0            0
simulator lru latch             629,084    0.0    0.4      0    1,672,383    0.1
sort extent pool                     77    0.0             0            0
transaction allocation          747,057    0.0             0            0
transaction branch alloc            316    0.0             0            0
undo global data                434,038    0.0    0.0      0            0
user lock                           282    0.0             0            0
          -------------------------------------------------------------
Latch Sleep breakdown for DB: SABO  Instance: SABO  Snaps: 28176 -28178
-> ordered by misses desc
                                      Get                            Spin &
Latch Name                       Requests      Misses      Sleeps Sleeps 1->4
-------------------------- -------------- ----------- ----------- ------------
row cache objects              62,209,555   2,636,047       1,501 2634552/1489/6/0/0
cache buffers chains          837,999,907   1,054,910       1,255 1053666/1233/11/0/0
library cache                  99,847,263     960,617       6,712 954009/6505/102/1/0
shared pool                    41,912,797     401,849       2,742 399208/2543/95/3/0
library cache pin              91,085,186     215,764         317 215450/311/3/0/0
row cache enqueue latch        62,201,242     112,183          77 112106/77/0/0/0
cas latch                      32,205,261      23,737          21 23716/21/0/0/0
multiblock read objects        18,762,943      22,925          48 22877/48/0/0/0
cache buffers lru chain           343,842       1,682          43 1640/41/1/0/0
mostly latch-free SCN             491,595       1,558           3 1555/3/0/0/0
library cache pin allocati      7,150,475         546           5 541/5/0/0/0
redo allocation                   957,456         394           2 392/2/0/0/0
session allocation                685,027         259           8 251/8/0/0/0
simulator lru latch               629,084         179          68 111/68/0/0/0
dml lock allocation               493,698         170           2 168/2/0/0/0
          -------------------------------------------------------------
Here is result of the script I run on our dabase:
-------------------------------------------------
SQL_TEXT_WO_CONSTANTS                                          COUNT(*)
------------------------------------------------------------ ----------
R_PACKAGE_BALANCES PKGBAL ,ER_RESOURCES RES WHERE PKGBAL.SUB
SCRIPTION_OBJ_ID IN (@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@
,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@
,@,@
 SELECT PURSRV.PURCHASED_SERVICE_OBJ_ID ,PURSRV.SUBSCRIPTION        121
_OBJ_ID ,PURSRV.STATUS_OBJ_ID ,PURSRV.PROV_STATUS_OBJ_ID ,PU
RSRV.SERVICE_ID ,PURSRV.PROVISIONING_TAG ,PURSRV.TIME_STAMP
,PURSRV.NON_REFUND_DESCRIPTION FROM ER_PURCHASED_SERVICES PU
RSRV WHERE PURSRV.SUBSCRIPTION_OBJ_ID IN (@,@,@,@,@,@,@,@,@,
@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,
SQL_TEXT_WO_CONSTANTS                                          COUNT(*)
------------------------------------------------------------ ----------
@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@,@
 SELECT OPTS.SUBSCRIPTION_OBJ_ID ,OPTS.DURATION ,OPTS.PROMO_        122
CODE ,OPTS.USER_GROUP ,OPTS.PAYMENT_TYPE ,OPTS.SUPPLIER_ID ,
OPTS.PREMIUM_LEVEL ,OPTS.CHANNEL ,OPTS.CHARGING_METHOD ,OPTS
.ACCESS_DEVICE ,OPTS.OPTION_OBJ_ID ,OPTS.OPTS_LOCK_ID ,MAX(O
PTS.TIME_STAMP) FROM ER_OPTIONS OPTS WHERE OPTS.SUBSCRIPTION
_OBJ_ID IN (@) GROUP BY OPTS.SUBSCRIPTION_OBJ_ID ,OPTS.DURAT
ION ,OPTS.PROMO_CODE ,OPTS.USER_GROUP ,OPTS.PAYMENT_TYPE ,OP
TS.SUPPLIER_ID ,OPTS.PREMIUM_LEVEL ,OPTS.CHANNEL ,OPTS.CHARG
ING_METHOD ,OPTS.ACCESS_DEVICE ,OPTS.OPTION_OBJ_ID ,OPTS.OPT
SQL_TEXT_WO_CONSTANTS                                          COUNT(*)
------------------------------------------------------------ ----------
S_LOCK_ID
 SELECT PKGBAL.AMOUNT ,PKGBAL.THRESHOLD ,PKGBAL.SUBSCRIPTION        122
_OBJ_ID ,RES.DESCRIPTION ,RES.RESOURCE_CODE ,RES.RESOURCE_TY
PE ,PKGBAL.BALANCE_OBJ_ID ,PKGBAL.PKG_BALANCE_LOCK_ID FROM E
R_PACKAGE_BALANCES PKGBAL ,ER_RESOURCES RES WHERE PKGBAL.SUB
SCRIPTION_OBJ_ID IN (@) AND PKGBAL.RESOURCE_OBJ_ID = RES.RES
OURCE_OBJ_ID
 SELECT DISTINCT SUBS.SUBSCRIPTION_OBJ_ID , SUBS.ACCOUNT_OBJ        238
_ID , SUBS.STATUS_OBJ_ID , SUBS.PACKAGE_ID , SUBS.START_DATE
SQL_TEXT_WO_CONSTANTS                                          COUNT(*)
------------------------------------------------------------ ----------
 , SUBS.END_DATE , SUBS.TIME_STAMP , SUBS.NEXT_CYCLE_DISCOUN
T , SUBS.IS_REFUNDABLE , SUBS.NON_REFUND_DESCRIPTION, SUBS.S
UBS_LOCK_ID , SUBS.SUPER_CREDIT_ID , SUBS.SUPER_CREDIT_BALAN
CE , DRM_DETAILS.DRM_DESCRIPTION, DRM_DETAILS.DRM_TYPE , DRM
_DETAILS.DRM_ID , SUBS.INTERACTIVE_USAGE_FLAG , COUNTRY.COUN
TRY_OBJ_ID, SUBS.BATCH_PROCESSOR
 SELECT DISTINCT SUBS.SUBSCRIPTION_OBJ_ID , SUBS.ACCOUNT_OBJ        243
_ID , SUBS.STATUS_OBJ_ID , SUBS.PACKAGE_ID , SUBS.START_DATE
 , SUBS.END_DATE , SUBS.TIME_STAMP , SUBS.NEXT_CYCLE_DISCOUN
T , SUBS.IS_REFUNDABLE , SUBS.NON_REFUND_DESCRIPTION , SUBS.
SQL_TEXT_WO_CONSTANTS                                          COUNT(*)
------------------------------------------------------------ ----------
SUBS_LOCK_ID , SUBS.SUPER_CREDIT_ID , SUBS.SUPER_CREDIT_BALA
NCE , PUR_SRV.SERVICE_ID , DRM_DETAILS.DRM_DESCRIPTION , DRM
_DETAILS.DRM_TYPE , DRM_DETAILS.DRM_ID , SUBS.INTERACTIVE_US
AGE_FLAG , SUBS.PROMOTIONAL , SUBS.BATCH_PROCESSOR , SUBS.PR
OMOTIONAL_EXPIRY_DATE ,
 SELECT DISTINCT SUBS.SUBSCRIPTION_OBJ_ID , SUBS.TIME_STAMP        2158
FROM ER_ACCOUNTS ACC, ER_SUBSCRIPTIONS SUBS, ER_OPTIONS OPTS
, ER_COUNTRY COUNTRY WHERE ACC.ACCOUNT_OBJ_ID = SUBS.ACCOUNT
_OBJ_ID AND SUBS.SUBSCRIPTION_OBJ_ID = OPTS.SUBSCRIPTION_OBJ
_ID(+) AND ACC.COUNTRY_OBJ_ID = COUNTRY.COUNTRY_OBJ_ID AND C
SQL_TEXT_WO_CONSTANTS                                          COUNT(*)
------------------------------------------------------------ ----------
OUNTRY.COUNTRY_CODE ='#' AND SUBS.STATUS_OBJ_ID=@ AND SUBS.S
UBSCRIPTION_OBJ_ID > @ AND SUBS.BATCH_RETRY_DATE IS NOT NULL
 AND SUBS.BATCH_RETRY_DATE <= TO_DATE('#','#') AND OPTS.CHAR
GING_METHOD=@ ORDER BY SUBS.SUBSCRIPTION_OBJ_ID ASC
8 rows selected.
Thank you for your help
Sam
 
June      13, 2008 - 10:08 am UTC 
 
you don't say how long this is for
we don't see how many parses you do (a parse is a parse - soft or hard - both require lots of latching, hard is just worse, soft is very bad, hard is very very bad)
you cannot tell anything from this - but it does look like lots of repeated sql there doesn't it. 
 
 
Sam Mousleh, June      13, 2008 - 10:41 am UTC
 
 
Sorry, I did not include the hall report, because it's so big and we are limited to 1000 words maximum.
I will try again to send it.
Sam 
June      13, 2008 - 10:54 am UTC 
 
it is 32k, not words...
 
 
 
Sam Mousleh, June      13, 2008 - 10:42 am UTC
 
 
Here is the first report section...
STATSPACK report for
DB Name         DB Id    Instance     Inst Num Release     Cluster Host
------------ ----------- ------------ -------- ----------- ------- ------------
SABO           310423053 SABO                1 9.2.0.6.0   NO      su1162
              Snap Id     Snap Time      Sessions Curs/Sess Comment
            --------- ------------------ -------- --------- -------------------
Begin Snap:     28176 05-Jun-08 13:00:03      489      28.1
  End Snap:     28178 05-Jun-08 14:00:03      484      27.8
   Elapsed:               60.00 (mins)
Cache Sizes (end)
~~~~~~~~~~~~~~~~~
               Buffer Cache:     7,008M      Std Block Size:          8K
           Shared Pool Size:       304M          Log Buffer:      1,024K
Load Profile
~~~~~~~~~~~~                            Per Second       Per Transaction
                                   ---------------       ---------------
                  Redo size:             68,109.68              1,936.06
              Logical reads:            126,505.31              3,596.00
              Block changes:                403.43                 11.47
             Physical reads:              6,577.85                186.98
            Physical writes:                 17.19                  0.49
                 User calls:                167.84                  4.77
                     Parses:                365.27                 10.38
                Hard parses:                  1.09                  0.03
                      Sorts:                515.41                 14.65
                     Logons:                  0.03                  0.00
                   Executes:             10,744.48                305.42
               Transactions:                 35.18
  % Blocks changed per Read:    0.32    Recursive Call %:     99.48
 Rollback per transaction %:    1.30       Rows per Sort:      5.69
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %:  100.00       Redo NoWait %:    100.00
            Buffer  Hit   %:   94.80    In-memory Sort %:    100.00
            Library Hit   %:   99.99        Soft Parse %:     99.70
         Execute to Parse %:   96.60         Latch Hit %:     99.58
Parse CPU to Parse Elapsd %:   92.98     % Non-Parse CPU:     99.63
 Shared Pool Statistics        Begin   End
                               ------  ------
             Memory Usage %:   95.36   97.92
    % SQL with executions>1:   69.27   69.89
  % Memory for SQL w/exec>1:   64.22   64.56
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~                                                     % Total
Event                                               Waits    Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
CPU time                                                       27,990    76.37
db file sequential read                         5,853,053       6,502    17.74
log file sync                                     105,494         793     2.16
log file parallel write                           108,260         698     1.90
db file scattered read                          4,206,900         538     1.47
          -------------------------------------------------------------
Wait Events for DB: SABO  Instance: SABO  Snaps: 28176 -28178
-> s  - second
-> cs - centisecond -     100th of a second
-> ms - millisecond -    1000th of a second
-> us - microsecond - 1000000th of a second
-> ordered by wait time desc, waits desc (idle events last)
                                                                   Avg
                                                     Total Wait   wait    Waits
Event                               Waits   Timeouts   Time (s)   (ms)     /txn
---------------------------- ------------ ---------- ---------- ------ --------
db file sequential read         5,853,053          0      6,502      1     46.2
log file sync                     105,494          0        793      8      0.8
log file parallel write           108,260          0        698      6      0.9
db file scattered read          4,206,900          0        538      0     33.2
buffer busy waits                  12,756          0         52      4      0.1
latch free                         12,800          0         22      2      0.1
log file sequential read              300          0         17     57      0.0
sbtwrite2                           1,191          0         11     10      0.0
control file parallel write         1,504          0          9      6      0.0
sbtbackup                               4          0          5   1307      0.0
SQL*Net more data to client        33,777          0          4      0      0.3
control file sequential read        4,669          0          2      0      0.0
sbtclose2                               4          0          1    327      0.0
sbtinfo2                                4          0          1    273      0.0
control file single write              32          0          1     26      0.0
SQL*Net break/reset to clien           19          0          1     27      0.0
enqueue                                26          0          0     18      0.0
sbtremove2                              2          0          0    220      0.0
log file switch completion              6          0          0     55      0.0
SQL*Net message from dblink           365          0          0      1      0.0
switch logfile command                  5          0          0     46      0.0
library cache pin                      24          0          0      6      0.0
sbtinit                                 8          0          0     14      0.0
local write wait                        9          0          0     11      0.0
log file single write                   8          0          0     11      0.0
single-task message                     1          0          0     40      0.0
LGWR wait for redo copy               157          0          0      0      0.0
wait list latch free                    1          0          0     25      0.0
log buffer space                        3          0          0      8      0.0
direct path read                    1,048          0          0      0      0.0
direct path write                     307          0          0      0      0.0
sbtend                                  8          0          0      0      0.0
SQL*Net message to dblink             365          0          0      0      0.0
async disk IO                         116          0          0      0      0.0
sbtinit2                                8          0          0      0      0.0
buffer deadlock                         1          1          0      0      0.0
SQL*Net message from client       782,399          0  1,434,920   1834      6.2
queue messages                      4,039      1,431     21,057   5213      0.0
virtual circuit status                120        120      3,489  29074      0.0
pipe get                               21          8         30   1441      0.0
SQL*Net message to client         782,394          0          1      0      6.2
SQL*Net more data from clien        1,132          0          0      0      0.0
          -------------------------------------------------------------
Background Wait Events for DB: SABO  Instance: SABO  Snaps: 28176 -28178
-> ordered by wait time desc, waits desc (idle events last)
                                                                   Avg
                                                     Total Wait   wait    Waits
Event                               Waits   Timeouts   Time (s)   (ms)     /txn
---------------------------- ------------ ---------- ---------- ------ --------
log file parallel write           108,260          0        698      6      0.9
control file parallel write         1,269          0          8      6      0.0
log file single write                   8          0          0     11      0.0
db file sequential read                44          0          0      1      0.0
rdbms ipc reply                        12          0          0      3      0.0
control file sequential read          796          0          0      0      0.0
LGWR wait for redo copy               157          0          0      0      0.0
enqueue                                 4          0          0      1      0.0
direct path read                    1,048          0          0      0      0.0
latch free                              4          0          0      0      0.0
direct path write                     306          0          0      0      0.0
log file sequential read                8          0          0      0      0.0
buffer busy waits                       1          0          0      0      0.0
rdbms ipc message                 110,090      4,210     22,846    208      0.9
pmon timer                          1,212      1,212      3,510   2896      0.0
smon timer                             19         10      3,465 ######      0.0
          -------------------------------------------------------------
 
June      13, 2008 - 10:56 am UTC 
 
Parses:                365.27 
you parse a lot, that requires the library cache latch.  But in this report, latch sleeps are not a major contributor to the wait time - but the latch gets are all contributors to the CPU time. 
 
 
Sam Mousleh, June      13, 2008 - 10:49 am UTC
 
 
Here is another important section of the report..
Thank you
Latch Miss Sources for DB: SABO  Instance: SABO  Snaps: 28176 -28178
-> only latches with sleeps are shown
-> ordered by name, sleeps desc
                                                     NoWait              Waiter
Latch Name               Where                       Misses     Sleeps   Sleeps
------------------------ -------------------------- ------- ---------- --------
cache buffers chains     kcbrls: kslbegin                 0        517      334
cache buffers chains     kcbgtcr: kslbegin excl           0        381      591
cache buffers chains     kcbgtcr: fast path               0        270      311
cache buffers chains     kcbchg: kslbegin: bufs not       0         19        9
cache buffers chains     kcbgcur: kslbegin                0         17        3
cache buffers chains     kcbzsc                           0         16        0
cache buffers chains     kcbzgb: scan from tail. no       0         12        0
cache buffers chains     kcbzib: multi-block read:        0          9        0
cache buffers chains     kcbchg: kslbegin: call CR        0          6        3
cache buffers chains     kcbgtcr: kslbegin shared         0          5        0
cache buffers chains     kcbcge                           0          1        0
cache buffers chains     kcbzib: finish free bufs         0          1        3
cache buffers chains     kcbzwb                           0          1        0
cache buffers lru chain  kcbzgb: multiple sets nowa  44,700         23        0
cache buffers lru chain  kcbbiop: lru scan              374         13        0
cache buffers lru chain  kcbzar: KSLNBEGIN           15,164          3        0
cache buffers lru chain  kcbzgm                       3,866          3        0
cache buffers lru chain  kcbzgb: posted for free bu   2,732          1       41
cas latch                kgsloupd1                        0         21       21
dml lock allocation      ktaiam                           0          2        2
library cache            kglic                            0      2,932       66
library cache            kglupc: child                    0      1,396    2,324
library cache            kglpnc: child                    0      1,101    3,183
library cache            kglpndl: child: before pro       0        247      341
library cache            kglpnp: child                    0        125      321
library cache            kgllkdl: child: cleanup          0        113       62
library cache            kglpin: child: heap proces       0        107       27
library cache            kglhdgc: child:                  0         56       41
library cache            kglobpn: child:                  0         49        8
library cache            kglpndl: child: after proc       0         47       10
library cache            kglhdgn: child:                  0         36       78
library cache            kglget: child: KGLDSBRD          0         30      126
library cache            kgldti: 2child                   0         16        2
library cache            kgldte: child 0                  0          7       27
library cache            kglobld                          0          2        1
library cache            kglpin                           0          1        1
library cache pin        kglpnc: child                    0        131      136
library cache pin        kglupc                           0        105      116
library cache pin        kglpndl                          0         47       24
library cache pin        kglpnp: child                    0         28       29
library cache pin        kglpnal: child: alloc spac       0          6       12
library cache pin alloca kgllkdl                          0          3        4
library cache pin alloca kglpnal                          0          2        1
mostly latch-free SCN    kcs01                            0          2        3
mostly latch-free SCN    kcs02                            0          1        0
multiblock read objects  kcbzib: mbr get                  0         27       29
multiblock read objects  kcbzib: normal mbr free          0         21       19
redo allocation          kcrfwr                           0          2        0
row cache enqueue latch  kqreqd                           0         58       22
row cache enqueue latch  kqreqa                           0         19       55
row cache objects        kqrpfl: not dirty                0      1,273      372
row cache objects        kqrpre: find obj                 0        228    1,129
session allocation       ksufap: active sessions          0          3        0
Latch Miss Sources for DB: SABO  Instance: SABO  Snaps: 28176 -28178
-> only latches with sleeps are shown
-> ordered by name, sleeps desc
                                                     NoWait              Waiter
Latch Name               Where                       Misses     Sleeps   Sleeps
------------------------ -------------------------- ------- ---------- --------
session allocation       ksucri                           0          2        6
session allocation       ksuxds: not user session         0          2        2
session allocation       ksuxds: KSUSFCLC not set         0          1        0
shared pool              kghalo                           0      1,351        4
shared pool              kghupr1                          0      1,103    2,737
shared pool              kghfrunp: clatch: nowait         0        289        0
shared pool              kghfrunp: alloc: wait            0        269        0
shared pool              kghfrunp: clatch: wait           0        158       94
shared pool              kghalp                           0         13        0
shared pool              kghfre                           0          4        1
shared pool              kghfen: not perm alloc cla       0          2        0
simulator lru latch      kcbs_simulate: simulate se       0         68       68
          -------------------------------------------------------------
Dictionary Cache Stats for DB: SABO  Instance: SABO  Snaps: 28176 -28178
->"Pct Misses"  should be very low (< 2% in most cases)
->"Cache Usage" is the number of cache entries being used
->"Pct SGA"     is the ratio of usage to allocated size for that cache
                                   Get    Pct    Scan   Pct      Mod      Final
Cache                         Requests   Miss    Reqs  Miss     Reqs      Usage
------------------------- ------------ ------ ------- ----- -------- ----------
dc_database_links                  192    0.0       0              0          1
dc_files                         7,600    0.0       0              0        152
dc_free_extents                     40    0.0       0              0          4
dc_global_oids                 330,886    0.0       0              0         87
dc_histogram_defs              174,807    0.1       0              0      1,231
dc_object_ids                  495,926    0.0       0              0        466
dc_objects                      30,967    0.3       0              8        951
dc_profiles                         81    0.0       0              0          1
dc_rollback_segments             5,134    0.0       0              0        130
dc_segments                     53,259    0.2       0             14        423
dc_sequences                     1,642    0.1       0          1,642         11
dc_tablespace_quotas                26   11.5       0             26         10
dc_tablespaces                 706,661    0.0       0              0         42
dc_user_grants                     900    0.0       0              0         26
dc_usernames                   132,405    0.0       0              0         14
dc_users                    29,161,512    0.0       0              0         29
          -------------------------------------------------------------
Library Cache Activity for DB: SABO  Instance: SABO  Snaps: 28176 -28178
->"Pct Misses"  should be very low
                         Get  Pct        Pin        Pct               Invali-
Namespace           Requests  Miss     Requests     Miss     Reloads  dations
--------------- ------------ ------ -------------- ------ ---------- --------
BODY                     736    0.7            856    0.6          0        0
CLUSTER                  382    0.5            302    1.3          0        0
INDEX                    130    2.3             67    4.5          0        0
PIPE                      52   23.1             65   18.5          0        0
SQL AREA             112,152    3.0     42,045,433    0.0        577        8
TABLE/PROCEDURE      478,013    0.0      3,765,359    0.0        382        0
TRIGGER                  248    0.0            248    0.0          0        0
          -------------------------------------------------------------
Shared Pool Advisory for DB: SABO  Instance: SABO  End Snap: 28178
-> Note there is often a 1:Many correlation between a single logical object
   in the Library Cache, and the physical number of memory objects associated
   with it.  Therefore comparing the number of Lib Cache objects (e.g. in
   v$librarycache), with the number of Lib Cache Memory Objects is invalid
                                                          Estd
Shared Pool    SP       Estd         Estd     Estd Lib LC Time
   Size for  Size  Lib Cache    Lib Cache   Cache Time   Saved  Estd Lib Cache
  Estim (M) Factr   Size (M)      Mem Obj    Saved (s)   Factr    Mem Obj Hits
----------- ----- ---------- ------------ ------------ ------- ---------------
        176    .6        161       41,309      485,708     1.0     181,573,120
        208    .7        192       50,285      485,711     1.0     181,574,848
        240    .8        223       59,446      485,714     1.0     181,575,905
        272    .9        255       68,780      485,720     1.0     181,579,173
        304   1.0        286       74,811      485,741     1.0     181,618,438
        336   1.1        318       78,529      485,763     1.0     181,687,097
        368   1.2        346       84,684      485,770     1.0     181,724,048
        400   1.3        362       89,476      485,771     1.0     181,724,742
        432   1.4        362       89,633      485,771     1.0     181,724,768
        464   1.5        362       89,633      485,771     1.0     181,724,768
        496   1.6        362       89,633      485,771     1.0     181,724,768
        528   1.7        362       89,633      485,771     1.0     181,724,768
        560   1.8        362       89,633      485,771     1.0     181,724,768
        592   1.9        362       89,633      485,771     1.0     181,724,768
        624   2.1        362       89,633      485,771     1.0     181,724,768
          -------------------------------------------------------------
SGA Memory Summary for DB: SABO  Instance: SABO  Snaps: 28176 -28178
SGA regions                       Size in Bytes
------------------------------ ----------------
Database Buffers                  7,348,420,608
Fixed Size                              752,080
Redo Buffers                          1,323,008
Variable Size                     3,137,339,392
                               ----------------
sum                              10,487,835,088
          -------------------------------------------------------------
SGA breakdown difference for DB: SABO  Instance: SABO  Snaps: 28176 -28178
Pool   Name                                Begin value        End value  % Diff
------ ------------------------------ ---------------- ---------------- -------
large  free memory                          33,554,432       33,554,432    0.00
shared 1M buffer                             2,099,200        2,099,200    0.00
shared Checkpoint queue                      4,106,240        4,106,240    0.00
shared FileOpenBlock                         6,773,240        6,773,240    0.00
shared KGK heap                                  7,000            7,000    0.00
shared KGLS heap                             1,606,168        1,131,072  -29.58
shared KQR L PO                              1,561,320        1,562,344    0.07
shared KQR M PO                              1,179,624        1,196,008    1.39
shared KQR S SO                                  7,424            7,424    0.00
shared KQR X PO                                 28,368           28,368    0.00
shared KSXR pending messages que               853,952          853,952    0.00
shared KSXR receive buffers                  1,034,000        1,034,000    0.00
shared MTTR advisory                           298,328          298,328    0.00
shared PL/SQL DIANA                          1,769,864        1,371,744  -22.49
shared PL/SQL MPCODE                         5,543,416        5,633,280    1.62
shared PLS non-lib hp                            3,216            3,216    0.00
shared VIRTUAL CIRCUITS                      2,073,680        2,073,680    0.00
shared branch                                  355,512          355,512    0.00
shared db_block_hash_buckets                30,574,480       30,574,480    0.00
shared db_handles                            1,044,000        1,044,000    0.00
shared dictionary cache                      3,229,952        3,229,952    0.00
shared enqueue                               1,654,896        1,654,896    0.00
shared errors                                   52,504          400,880  663.52
shared event statistics per sess            11,255,440       11,255,440    0.00
shared fixed allocation callback                 1,168            1,168    0.00
shared free memory                          19,458,928        8,740,712  -55.08
shared joxs heap init                            4,240            4,240    0.00
shared krvxrr                                  253,056          253,056    0.00
shared ksm_file2sga region                     370,496          370,496    0.00
shared ktlbk state objects                     586,384          586,384    0.00
shared library cache                        70,989,544       73,428,504    3.44
shared miscellaneous                        60,497,992       60,358,832   -0.23
shared parameters                              157,784          164,384    4.18
shared pl/sql source                               640              584   -8.75
shared processes                             1,180,800        1,180,800    0.00
shared sessions                              2,690,480        2,690,480    0.00
shared sim memory hea                        7,301,888        7,301,888    0.00
shared sim trace entries                       393,216          393,216    0.00
shared sql area                            177,103,016      185,982,000    5.01
shared table definiti                            6,552            1,344  -79.49
shared transaction                             954,448          954,448    0.00
shared trigger defini                              544              544    0.00
shared trigger inform                            1,808            1,680   -7.08
shared trigger source                              168              168    0.00
shared type object de                          322,360          321,216   -0.35
       buffer_cache                      7,348,420,608    7,348,420,608    0.00
       fixed_sga                               752,080          752,080    0.00
       log_buffer                            1,312,768        1,312,768    0.00
          -------------------------------------------------------------
init.ora Parameters for DB: SABO  Instance: SABO  Snaps: 28176 -28178
                                                                  End value
Parameter Name                Begin value                       (if different)
----------------------------- --------------------------------- --------------
aq_tm_processes               0
background_dump_dest          /product/oracle/sgbd/SABO/bdump
compatible                    9.2.0.6
control_files                 /database/oracle/SABO/CTL_SABO_00
core_dump_dest                /product/oracle/sgbd/SABO/cdump
db_block_size                 8192
db_cache_size                 7348420608
db_domain
db_file_multiblock_read_count 16
db_name                       SABO
dispatchers                   (PROTOCOL=TCP) (SERVICE=SABOXDB)
fast_start_mttr_target        300
hash_join_enabled             TRUE
instance_name                 SABO
java_pool_size                0
job_queue_processes           10
large_pool_size               33554432
local_listener                LSNR_SABO_01_LOC
log_archive_dest              /product/oracle/sgbd/SABO/arch
log_archive_format            arc_SABO_%s.arc
log_archive_start             TRUE
log_buffer                    1048576
open_cursors                  5000
optimizer_mode                CHOOSE
os_authent_prefix             ops$
pga_aggregate_target          7340032000
processes                     900
query_rewrite_enabled         FALSE
remote_login_passwordfile     EXCLUSIVE
service_names                 su1162_SABO, SABO
sga_max_size                  10487835088
shared_pool_size              318767104
star_transformation_enabled   FALSE
timed_statistics              TRUE
undo_management               AUTO
undo_retention                50000
undo_tablespace               UNDO_001_SABO
user_dump_dest                /product/oracle/sgbd/SABO/udump
utl_file_dir                  /varsoft/sabo/trace/tmp, /varsoft
workarea_size_policy          auto
 
June      13, 2008 - 10:57 am UTC 
 
and according to that, increasing the shared pool would do nothing.  You just parse a lot, soft parsing
you might utilize session_cached_cursors if an application tends to parse and reparse the same sql over and over  
 
 
Sam Mousleh, June      13, 2008 - 12:23 pm UTC
 
 
Tom, I thought soft parse is good and we should avoid only hard parse. Parses: 365.27  and 10.38 per transaction.
1. Do you mean we parse a lot per transaction.
2. Are you saying if I increasing the shared pool nothing will change.
About session_cached_cursors I read so many articles that it does not improve respond time. it might improve parsing a little but not respond time. 
Can I set the session_cached_cursors at database level I mean in the spfile or init.ora file.
Also you said at the begining that (a parse is a parse - soft or hard - both require lots of latching, hard is just worse, soft is very bad, hard is very very bad) so how we can avoid both parse hard and soft then.
Thank you again
Sam 
June      13, 2008 - 1:25 pm UTC 
 
there are three types of parses in Oracle:
a hard parse.  It is very very very bad.
a soft parse.  It is simply very very bad.
the absence of a parse, this is the only good parse going.
1) you parse a lot per second!  that was a parse per second count, each parse takes lots of CPU, latching and you do 365.27 of them on average every single second.  
2) that is what the shared pool advisor, which is watching your system and your workload and what you do is saying.
The programmers are the only ones that can avoid a parse.  They have code that looks like:
parse sql
bind (hopefully this is there!!!!)
execute sql
close sql
in a routine that gets called frequently, that should be:
if (first_time)
then
   parse sql
   first_time gets false
end
bind sql
execute sql
/* do not close it */
If they move all of their SQL into PLSQL - this will happen almost automagically !!!  PLSQL caches sql - when you say "close cursor" in plsql, plsql laughs at you and says "no way, you are just going to execute it again, I'll keep it open for you".  The developers would still have to parse the CALL to plsql once and cache that statement handle, but they wouldn't have to worry about the rest of the SQL.
session_cached_cursors is best set at the init.ora level, yes. 
 
 
Sam Mousleh, June      16, 2008 - 6:30 am UTC
 
 
I am sorry Tom, but I didn't realy get what you are saying about not closing sql after execute sql!!! how can you close or open sql statement?
if (first_time)
then
   parse sql
   first_time gets false
end
bind sql
execute sql
/* do not close it */
All sql's statements is in plsql procedures... and there is so many procedures in this application. many procedures that is calling many other procedures with loops and conditions and SELECT COUNT(*)... and so on,
I am trying to improve performance of the procedure that of course calls other procedures to do the job. we are reaching TIME OUT "over a 1 minutes and 10 seconds".
Thank you again,
Sam 
June      16, 2008 - 12:10 pm UTC 
 
your programmers know how to do this - they are the ones you need to talk to.  If you don't know how to open and close sql - well, they do.
Since everything is in plsql, you as the "dba" control the size of the plsql cursor cache via session_cached_cursors - what is yours set to?  You might consider increasing it.
It is unlikely this is the cause of you taking more than 1:10 to execute, that would more likely be "inefficient code" 
 
 
Library latch contention
Chris, July      29, 2008 - 12:22 pm UTC
 
 
Tom,
   I have a 10.2.0.3 database that I believe is experiencing library latch contention (among other things).  In the Top SQL Statements of the ASH report I have 51.67% for the PL/SQL block generated by a web server request.  That 51.67% breaks down as follows in the %Event column):
18.97 cursor: pin S wait on X
16.11 CPU + Wait for CPU
12.54 kksfbc child completion
I thought I read the "cursor: pin S wait on X" was a new term for library latches?
Two other very concerning entries come from the AWR.  The application is an OLTP type app that does tens of millions of transactions over a several hour time period.  When I compare stats from the new code to benchmarked code (for a 10 or 15 minute period) I see the following:
Parse CPU to Parse Elapsd %: went from 62.13 to 4.74
Soft Parse %: went from 99.99 to 81.65
% Non-Parse CPU: went from 99.61 to 93.38
I have used your code to strip literals and numbers from v$sqlarea and look for bad SQL (without binds) and found nothing (which I sort of expected since the application is 99% PL/SQL and the binding should be done for me and there is very little dynamic SQL).
The noticeable difference is that machine CPU is now being pegged whereas it used to run much more efficiently.  Looking for any suggestions on where to look and am I even on the right track.
I will note that with the new code that has been added there are a lot of selects from PL/SQL tables using CAST(TABLE with CARDINALITY hints.  I have no idea if that should affect anything and have given thought to recoding using global temp tables but would be a ton of programming effort (man months) I don't want to go through if it's not even the right track.
I know you love details and this may sound somewhat vague, I'm just at a loss as to what details to provide because I'm not sure where to go with this.  The system is a shop floor type app with all action coming through thousands of simultaneous web server connections from plant floor devices so tracing individual sessions isn't very practical, but I could do it at the system level for a couple minutes if I knew what to then go look for in the monstrous trace file I'd get.
Thoughts on how to proceed? 
 
10.2.0.3 - RAC
Dirtbag1402, August    13, 2008 - 10:59 am UTC
 
 
If you're hitting this:
18.97 cursor: pin S wait on X
16.11 CPU + Wait for CPU
12.54 kksfbc child completion
I'd say you're hitting Oracle Bug: 6477136 - but it appears to be a Real Application Clusters issue.  We get this problem when the shared pool has been flushed or the DB bounced, and I think it's related to Oracle's ASMM, where the various memory structures are resized.  Possibly also related to cursor_sharing setting.
I'd look into this bug, sadly the base bug isn't visible so an SR may be required. 
 
simulate library cache latch,
A reader, August    21, 2008 - 1:30 pm UTC
 
 
How to simulate library cache latch in our 10gR2 environment?
Also, I once tried executing SQL quering on v$ views (pretty big SQL with more than 400 characters) and that was waiting for library cache latch.  In the RAW trace file, it showed it is waiting on different object (user defined index) which I am not using my query at all.
How is this possible?  
At that time, there was heavy parsing by user application and perhaps one of their SQL was waiting for library cache latch (not sure).
In this situation will my big query also end up in library cache latch?  I tried small query something like "select * from v$session where sid=nnn" and that worked without any delay.
Does library cache latch happens if there is no enough room (enough chunks of memory) in the shared pool?
Does library cache latch happen if the alloted latches at the database level are exhausted by latching other cursors?
How does CURSOR_SHARING parameter values(all the 3 values) affect the library cache latch?
Appreciate your response.
Thanks,
 
August    21, 2008 - 10:13 pm UTC 
 
I don't know what you mean by simulate a latch.
I don't know what was in your trace file, you'd have to give us an example to look at.
What do you mean by "a pretty big sql with more than 400 characters"????  do you mean "just a long sql string" - if you do, 400 is small and even if it were 40,000 or 400,000 that doesn't matter - that won't increase the time we hold a latch really - we use latches to serialize access to data structures, things we go in and get out really fast.  We'd take your big query and break it into tokens - really small bits and pieces - and then look up the bits and pieces, bit by bit.  There would not be a long latch held for a 'big' query.
the library cache latch is used to safely access the shared data structure that is the library cache in the SGA.  When I'm reading from it, you cannot be modifying (loading into) it.  So, we use a latch to serialize - very very quickly. 
 
 
40000 long string?
reader, August    22, 2008 - 4:29 am UTC
 
 
I don't think oracle support 40,000 characters long sql string as a single SQL statement. 
August    22, 2008 - 9:47 am UTC 
 
sure it does, there is actually no documented limit.
You can do a sql statement as big as you like........
even in plsql - you have to use dbms_sql to do it there, but even in plsql (there is a parse API that takes a plsql table of strings, each string is a "line" of text and you can have really large strings).
 
 
 
SQL query length limit
A reader, August    23, 2008 - 3:01 pm UTC
 
 
"sure it does, there is actually no documented limit. "
My application submitted a 744,265 character long SQL query via JDBC. It's been hanging for over 20 hours. V$SQL doesn't show any activity, no executions, disk reads, buffer gets, nothing. V$SESSION shows the query waiting on "SQL*Net more data from client". 
One of Millsap's case studies featured in his book indicates the follwing regarding the more data from client event:
"The long SQL text strings wouldn¿t fit into a single SQL*Net packet, so the Oracle kernel spent a considerable amount of time awaiting second and subsequent SQL*Net packets during parse calls."
Any chance this is what's holding up my query from running?
Thanks. 
August    26, 2008 - 8:04 pm UTC 
 
given what you supply us - not much - I cannot comment on what is happening.  We don't know (and don't really want to see) what a 750k sql statement looks like - if it was
select *
from dual, dual, dual, dual, dual, ....... lots and lots of duals, dual;
then it would be the optimizer going into high gear and doing lots of work. 
 
 
Huge IN list
A reader, August    27, 2008 - 12:16 am UTC
 
 
The 750K query has an IN list of 43,000 items. We are going to change the query to avoid having a large IN list but I'd like to know if such a large query could be "hanging" due to a more data from client wait event.
 
August    27, 2008 - 8:31 am UTC 
 
you can see what a session is waiting on in the v$ views, query them.
That needs to be fixed - like soon.  That query should be tiny, select * from t where c in ( select * from global_temporary_table );
that inlist should never have been generated, it should have been at best stuffed into a global temporary table and used from there. 
 
 
Global temp table
A reader, August    27, 2008 - 9:14 am UTC
 
 
That's exactly what we did, use a global temp table and it works great. The session was waiting for "more data from client" back when it was hanging. 
 
No new lines
A reader, October   09, 2008 - 10:08 am UTC
 
 
A few more questions regarding the long SQL statement I mentioned above. 
The scenario I described had the application "hanging" and the database waiting for "more data from client". I recently discovered the application's Java code builds the SQL statement as a single string of characters with no embedded new lines. If we were to print the SQL it would show as one very long line. 
Does a very long SQL string (with no new lines) cause the database to wait on "more data from client"? 
Can I assume the entire SQL was received by the database because I found it in V$SQL? 
We already fixed this issue by using a global temp table. My questions are more curiosity than anything else.
Thanks.
 
October   09, 2008 - 11:18 am UTC 
 
... Does a very long SQL string (with no new lines) cause the database to wait on 
"more data from client"? 
 ..
only in the event of a bug, one that I am not personally aware of.
eg: there is no restriction on the length of a sql statement - with or without newlines.
...
Can I assume the entire SQL was received by the database because I found it in 
V$SQL? 
.....
yup - how else could it have gotten there? 
 
 
remove_constants: Not in 10.2.0.3
Richard, November  20, 2008 - 1:54 pm UTC
 
 
Try as I might, I cannot get remove_constants to work in 10g )10.2.0.3) Linux.
The problem lies with:
update t1 set sql_text_wo_constants = remove_constants(sql_text);
Here's the error:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SYSTEM.REMOVE_CONSTANTS", line 10
Works on 9i. 
November  24, 2008 - 1:20 pm UTC 
 
if your line 10 is my line 10, that is:
ops$tkyte%ORA10GR2> create or replace function
  2  remove_constants( p_query in varchar2 ) return varchar2
  3  as
  4      l_query long;
  5      l_char  varchar2(1);
  6      l_in_quotes boolean default FALSE;
  7  begin
  8      for i in 1 .. length( p_query )
  9      loop
 10          l_char := substr(p_query,i,1);
 11          if ( l_char = '''' and l_in_quotes )
 12          then
and I would suspect is has nothing to do with the version - everything to do with multi-byte character sets.
varchar2(1) is one byte - maybe it needs be
  1  create or replace function
  2  remove_constants( p_query in varchar2 ) return varchar2
  3  as
  4      l_query long;<b>
  5      l_char  varchar2(1 CHAR);</b>
  6      l_in_quotes boolean default FALSE;
  7  begin
for your multibyte data.. 
 
 
 
Never Doubted You!
Richard, February  17, 2009 - 1:12 pm UTC
 
 
Worked! Thanks! 
 
What about...
Richard, June      11, 2009 - 6:15 am UTC
 
 
I love the Am I Using Binds query, and have used it to great effect on many occasions.
I use it to prove that a shop is not being as efficient as it could be, and it is usually well-received... BUT... what I'd also like to be able to do based (I expect)
on the script is to show how much Shared Pool, in megabytes/whatever, is being wasted.
Is there a way to do that?
This is a new question, but, I feel, is a natural corollary to the replies thus far given
 
June      11, 2009 - 10:52 am UTC 
 
.. what I'd also like to be able to do based (I 
expect)
on the script is to show how much Shared Pool, in megabytes/whatever, is being 
wasted.
....
the answer to that is simple:
100%, 100% of the shared pool is being destroyed by this practice.
Here is a script I run to "prove" that out, to demonstrate that:
ops$tkyte%ORA11GR1> create table t ( x int primary key );
Table created.
ops$tkyte%ORA11GR1>
ops$tkyte%ORA11GR1> select count(*) from v$sql where sql_text NOT LIKE 'select /* nobind */ * from t where x = %';
  COUNT(*)
----------
       684
ops$tkyte%ORA11GR1> pause
ops$tkyte%ORA11GR1>
ops$tkyte%ORA11GR1> set timing on
ops$tkyte%ORA11GR1> declare
  2      l_cursor sys_refcursor;
  3  begin
  4      for i in 1 .. 10000
  5      loop
  6          open l_cursor for 'select /* nobind */ * from t where x = ' || i;
  7          close l_cursor;
  8      end loop;
  9  end;
 10  /
PL/SQL procedure successfully completed.
Elapsed: 00:00:13.70
ops$tkyte%ORA11GR1> declare
  2      l_cursor sys_refcursor;
  3  begin
  4      for i in 1 .. 10000
  5      loop
  6          open l_cursor for 'select /* bind */ * from t where x = :x' using i;
  7          close l_cursor;
  8      end loop;
  9  end;
 10  /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.85
ops$tkyte%ORA11GR1>
ops$tkyte%ORA11GR1> set linesize 121
ops$tkyte%ORA11GR1> select count(*), to_char(sum(sharable_mem),'999,999,999') sm,
  2         to_char(sum(sharable_mem)/ decode( count(*), 0, to_number(null), count(*) ), '999,999,999' ) per_stmt
  3    from v$sql
  4   where sql_text like 'select /* nobind */ * from t where x = %';
  COUNT(*) SM           PER_STMT
---------- ------------ ------------
       353    3,107,841        8,804
Elapsed: 00:00:00.19
ops$tkyte%ORA11GR1>
ops$tkyte%ORA11GR1> select count(*), to_char(sum(sharable_mem),'999,999,999') sm
  2    from v$sql
  3   where sql_text = 'select /* bind */ * from t where x = :x';
  COUNT(*) SM
---------- ------------
         1       12,892
Elapsed: 00:00:00.03
ops$tkyte%ORA11GR1>
ops$tkyte%ORA11GR1> select count(*) from v$sql where sql_text NOT LIKE 'select /* nobind */ * from t where x = %';
  COUNT(*)
----------
       433
things to note:
1) we did 10,000 hard parses - why are there are only 353 in the shared pool?  because we filled it up, flushed it, filled it, flushed it, etc.... 
2) why did the count of nobind sql drop from 684 to 433 - because when we flush, we flush - anything we can.  That bind nobind sql came in and basically kicked out a lot of 'good' sql - sql that will now be implicitly hard parsed next time.
One bad unbound sql statement
In one bad application
executed frequently enough
is sufficient to destroy the entire shared pool 
 
 
free global transaction table entry
Mozammel Hoque, July      21, 2009 - 4:20 am UTC
 
 
SQL> SELECT event, state, p1, p2, p3
  2  FROM   v$session_wait
  3  WHERE  sid = 2807;
EVENT                                    STATE                       P1         P2         P3
---------------------------------------- ------------------- ---------- ---------- ----------
free global transaction table entry      WAITING                  47497          0          0
SQL> SELECT event#, event_id, name, parameter1, wait_class_id, wait_class#, wait_class 
  2  FROM v$event_name WHERE name = 'free global transaction table entry';
    EVENT#   EVENT_ID NAME                                   PARAMETER1   WAIT_CLASS_ID WAIT_CLASS# WAIT_CLASS
---------- ----------  -------------------------------------- ------------ ------------- -----------  -----
       629 1932123989 free global transaction table entry    tries           1893977003           0 Other
How can we get rid of wait event "free global transaction table entry"? 
 
 
library cache load lock
kulbhushan, November  04, 2009 - 1:28 pm UTC
 
 
Hi tom, We faced database hung on 3 node 11i erp rac 
database.We saw the libracy cache load lock timed out events reported in alert log. Then few ora-600 and later ROW CACHE ENQUEUE LOCK timed out event. Eventually database was hung and we had to bouce services .
we created support sr 7845542.992 for RCA.
The support says to increase shared pool size to avoid shared pool fragmentation and avoid reload ,additionaly to upgrade to 10g database.
I am covinced adding additional pool size would solve this or upgrade to 10 .furthermore even 10g has such issues reported.
I saw couple of bugs mentioned such issue can happen due deadlock of session holding latches .kindly let me know your view on issue
. Regards
 
 
Regexp version
Donat Callens, May       26, 2010 - 4:47 am UTC
 
 
Hi Tom,
Hereby a regular expression version of the query to find statements that are identical in the shared pool:
SELECT COUNT (*),
   sql_text_wo_constants
FROM
   (SELECT  regexp_replace (
               regexp_replace (
                  regexp_replace (
                     sql_text,
                     '([^'']+'')[^'']+''', -- find quoted strings
                     '\1#''' -- replace them with '#'
                  ),
                  '([^[:alnum:]])[[:digit:]]+([^[:alnum:]])', -- find numbers
                  '\1@\2' -- replace them with @
               ),
               ' +', -- find blank spaces
               ' ' -- replace them with single space
            ) AS sql_text_wo_constants
   FROM v$sqlarea
   )
GROUP BY sql_text_wo_constants
HAVING COUNT (*) > 100
ORDER BY 1 DESC;
Notes:
1. The sub-query is only there to avoid typing the regular expression statement twice.
2. This query avoids the issue with variables having digits in their name. I.E. 'select value11, value12, (...)' is not handled correctly by the remove_constant function
3. Your version is much, much faster... I know!
Donat 
 
Using bind variables in proc
rakesh, June      30, 2011 - 11:59 pm UTC
 
 
HI Tom,
select sql_text_wo_constants, count(*)
  from t1
 group by sql_text_wo_constants
having count(*) > 100
 order by 2
/
SQL_TEXT_WO_CONSTANTS                                                                                  COUNT(*)
---------------------------------------------------------------------------------------------------- ----------
BEGIN :L_RET_VALUE := ABC.P_PROVISIONING_ABC.ABC_ANRAX(@ ,@ ,'#' ,'#'); END;                            2880
BEGIN :L_RET_VALUE := ABC.P_PROVISIONING_ABC.ABC_LAC(@ ,@ ,'#' ,'#'); END;                              4156
BEGIN :L_RET_VALUE := ABC.P_PROVISIONING_ABC.ABC_DIRECTORY_NUMBER(@ ,@ ,'#' ,'#'); END;                 8813
BEGIN P_PROVISIONINGMANAGER_API.UPDATE_SOP_OBJECTS ('#','#','#'); END;                                   13464
i got the above output, As the count is in 5 digits. I really need to work on it to stabilize my database. The above procedures are called by the application. 
1)How to pass bind variables while calling the procedure?
2)If it is not possible,is there any other work around. Please suggest me as i am very new to DBA and got lot of issues on my database. 
July      01, 2011 - 9:16 am UTC 
 
1) the same way you pass bind variables to anything - look - they know how to bind for the output - it is pretty much similar for the inputs.
2) it is very possible.  The developers already know how to bind, they are getting the outputs! tell them just to bind the inputs as well.  
The syntax for that is dependent on the language you are using/programming in.  But binding to the plsql block will be the same as binding to SQL. 
 
 
Wait Event - latch: cache buffers chains
Jim Cox, January   12, 2012 - 10:53 am UTC
 
 
Hi Tom
I have been trying to figure out why some vendor sql at times takes 2 minutes to run and at other time takes hours.
The sql does not use bind variables, so i know that is an issue. I ran your sql from above and i do not see the sql listed that is taking a long time to run, so I am missing something.
Here is the OEM Wait History for the sql when it does not complete properly. Is there any other reason other than not using bind variables that would cause cache buffer chains ?
What do you suggest I do next ?
Thanks
Jim
Wait Class Wait Event   P1 Test  P1 P2 Text  P2  P3 Text  P3 Wait Time
Concurrency latch: cache buffers chains address   number  124 tries    0
Concurrency latch: cache buffers chains address   number  124 tries    0
Concurrency latch: cache buffers chains address   number  124 tries    1
Concurrency latch: cache buffers chains address   number  124 tries    2
Concurrency latch: cache buffers chains address   number  124 tries    4
Concurrency latch: cache buffers chains address   number  124 tries    1
Concurrency latch: cache buffers chains address   number  124 tries    1
Concurrency latch: cache buffers chains address   number  124 tries    1
Concurrency latch: cache buffers chains address   number  124 tries    1
Concurrency latch: cache buffers chains address   number  124 tries    0
  
January   13, 2012 - 9:13 am UTC 
 
when you run it and it runs 'fast', what else is going on in the database - when slow - what else is going on?
I'd guess that when 'slow', there are lots of other users or some big batch job - and they are doing IO and they are competing with each other for the buffer cache.
 
 
 
Wait Event - latch: cache buffers chains - Followup
Jim Cox, January   13, 2012 - 2:26 pm UTC
 
 
 
Diff between "library cache lock" and "library cache pin" 
Rakesh, January   21, 2012 - 7:01 am UTC
 
 
Hi Tom,
1)What is the between "library cache lock " and "library cahe pin". 
2)Can you give us some examples on,when there will be a "lock" and "pin" 
January   21, 2012 - 10:40 am UTC 
 
 
 
Library cache pin
Rakes, January   23, 2012 - 11:34 pm UTC
 
 
HI tom,
I am still not clear with licrary cache pin. Your link says that, 
"an underlying objects should not be modified when a session is executing or accessing a dependent object (SQL). So, before parse locks on a library cache object can be broken, library cache pins must be acquired in Exclusive mode and then only library cache objects can be dropped. If a session is executing an SQL, then library cache pins will not be available and there will be waits for library cache pins. Typically, this happens for long running SQL statement. 
"
If i am running "select * from emp" from session 1,where emp table is a pretty huge table and it takes around 1 hr to complete.
If i run the same query from session 2, will session 2 wait on "library cache pin" till the session 1 gets completed?
Thanks a lot
 
January   24, 2012 - 1:24 pm UTC 
 
consider a pin a lock, a lock a pin, the semantic difference to us is too minor.
If i am running "select * from emp" from session 1,where emp table is a pretty 
huge table and it takes around 1 hr to complete.
If i run the same query from session 2, will session 2 wait on "library cache 
pin" till the session 1 gets completed?
absolutely NOT.  
It is DDL they are trying to prevent, not DML 
 
 
latch : shared pool wait event
aliyar, February  07, 2012 - 1:27 am UTC
 
 
Dear tom ,
o/s : linux
database : 11gr2
i have taken awr report for one hour time duration
              Snap Id      Snap Time      Sessions Curs/Sess
            --------- ------------------- -------- ---------
Begin Snap:      5236 06-Feb-12 18:00:33       126       4.2
  End Snap:      5237 06-Feb-12 19:00:53        93       3.2
   Elapsed:               60.33 (mins)
   DB Time:            
Event                                 Waits     Time(s)   (ms)   time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
cursor: pin S                        51,214      32,594    636   41.9 Concurrenc
latch: shared pool                   23,610      17,529    742   22.6 Concurrenc
cursor: mutex S                      23,827      13,235    555   17.0 Concurrenc
DB CPU                                           10,688          13.8
log file sync                       877,048       4,089      5    5.3 Commit
found that cursor: pin and latch: shared pool are top waits in the database.
i tried to understand about latch: shared pool  wait and its fixes from google and metalink. but i could not anything usefully.
can you please help me to understand the above said wait event and fix for that wait
Thanks
Aliyar 
February  08, 2012 - 1:19 am UTC 
 
there are two 'fixes'
a) cut down on your concurrent users - 126 sessions - so you have 32 to 64 cores on your server?  
b) cut down on your parsing - especially hard parsing, you don't share your soft parse %, but I'll bet it is a number way lower than 90%.  If it is, you not only have a performance bug inflicted by your programmers, but a severe security bug as well (called sql injection) 
 
 
 
latch : shared pool wait event   
aliyar, February  13, 2012 - 1:04 pm UTC
 
 
dear Tom,
thanks for your immediate reply for the previous question about " latch : shared pool wait event " . i have taken awr report from good time and bad time . result as follows
Good time report taken 01 hour interval
Host Name        Platform                         CPUs Cores Sockets Memory(GB)
---------------- -------------------------------- ---- ----- ------- ----------
xxxxxxxxxx Linux x86 64-bit                    4     4       2      31.28
              Snap Id      Snap Time      Sessions Curs/Sess
            --------- ------------------- -------- ---------
Begin Snap:      5403 13-Feb-12 17:00:15       163       4.8
  End Snap:      5404 13-Feb-12 18:00:36       149       5.1
   Elapsed:               60.34 (mins)
   DB Time:              363.79 (mins)
Load Profile              Per Second    Per Transaction   Per Exec   Per Call
~~~~~~~~~~~~         ---------------    --------------- ---------- ----------
      DB Time(s):                6.0                0.0       0.01       0.01
       DB CPU(s):                1.4                0.0       0.00       0.00
       Redo size:        2,787,450.0            6,975.8
   Logical reads:           33,314.5               83.4
   Block changes:           10,532.5               26.4
  Physical reads:            4,662.5               11.7
 Physical writes:              654.3                1.6
      User calls:              509.0                1.3
          Parses:               85.2                0.2
     Hard parses:                0.9                0.0
W/A MB processed:                1.0                0.0
          Logons:                0.5                0.0
        Executes:              445.5                1.1
       Rollbacks:                0.0                0.0
    Transactions:              399.6
Top 5 Timed Foreground Events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                           Avg
                                                          wait   % DB
Event                                 Waits     Time(s)   (ms)   time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
db file sequential read           4,013,902       6,481      2   29.7 User I/O
DB CPU                                            4,874          22.3
log file sync                     1,442,402       4,405      3   20.2 Commit
direct path read                    284,571       1,595      6    7.3 User I/O
latch: shared pool                   19,107       1,239     65    5.7 Concurrenc
Host CPU (CPUs:    4 Cores:     4 Sockets:    2)
~~~~~~~~         Load Average
               Begin       End     %User   %System      %WIO     %Idle
           --------- --------- --------- --------- --------- ---------
                5.09      6.00      30.1       7.6      26.5      60.1
=======================================================
=========================================================
Bad Time report 01 hour interval
              Snap Id      Snap Time      Sessions Curs/Sess
            --------- ------------------- -------- ---------
Begin Snap:      5236 06-Feb-12 18:00:33       126       4.2
  End Snap:      5237 06-Feb-12 19:00:53        93       3.2
   Elapsed:               60.33 (mins)
   DB Time:            1,295.40 (mins)
Load Profile              Per Second    Per Transaction   Per Exec   Per Call
~~~~~~~~~~~~         ---------------    --------------- ---------- ----------
      DB Time(s):               21.5                0.1       0.09       0.07
       DB CPU(s):                3.0                0.0       0.01       0.01
       Redo size:        1,879,295.1            7,753.1
   Logical reads:           10,841.6               44.7
   Block changes:            6,955.0               28.7
  Physical reads:              104.3                0.4
 Physical writes:              388.2                1.6
      User calls:              294.2                1.2
          Parses:               47.4                0.2
     Hard parses:                0.3                0.0
W/A MB processed:                0.2                0.0
          Logons:                0.0                0.0
        Executes:              249.2                1.0
       Rollbacks:                0.0                0.0
    Transactions:              242.4
Top 5 Timed Foreground Events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                           Avg
                                                          wait   % DB
Event                                 Waits     Time(s)   (ms)   time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
cursor: pin S                        51,214      32,594    636   41.9 Concurrenc
latch: shared pool                   23,610      17,529    742   22.6 Concurrenc
cursor: mutex S                      23,827      13,235    555   17.0 Concurrenc
DB CPU                                           10,688          13.8
log file sync                       877,048       4,089      5    5.3 Commit
Host CPU (CPUs:    4 Cores:    4 Sockets:    2)
~~~~~~~~         Load Average
               Begin       End     %User   %System      %WIO     %Idle
           --------- --------- --------- --------- --------- ---------
               25.17      6.48      54.4      23.8       2.3      20.8
SQL> show parameter cursor_sharing
NAME_COL_PLUS_SHOW_P TYPE                             VALUE_COL_
-------------------- -------------------------------- ----------
cursor_sharing       string                           force
SQL>
concurrency user count is less in bad time while comparing with good time. i dont find any hard parsing issue from the above report.
could you please give me some more guidence on this issue
Thanks
Aliyar 
 
February  13, 2012 - 2:09 pm UTC 
 
during 'good' time you had an AVERAGE of 6 seconds in the database for every one second of real time.
Given you have four cores - that is OK (maybe).  Think about it - it means that ON AVERAGE over that one hour period - every single second had six people active constantly.
Your CPU utilization looks like it was in the 40-50% range.
Now, during your 'bad' time - you had an an AVERAGE of 21.5 seconds of database time per every single second.  That is 21.5 sessions all trying to do stuff (on a four core machine remember) at exactly the same time! 
Give  you have four cores, that is not OK.  Think about it - it means that ON AVERAGE over that one hour period - every single second had 21/22 people active constantly.
I've emphasized ON AVERAGE - for I'd bet a lot of money that there were times during that hour that WAY MORE than 21 people were trying to be active.
See how you do more work in each second on average when your average concurrency is six/second than you do when it is 21.5/second?  You can do MORE WORK with LESS CONCURRENT users.
I'm not talking about sessions, I'm talking about real concurrency.  Concurrent active sessions.
I'll stand by my original answer. 
You do have a parsing problem - you have cursor sharing=force trying to hide from it.  Your developers did it wrong.  SQL Injection is something you have to worry about as well!
Why do you have over 100 connected sessions to a 4 core machine?
Why do you let so many sessions (way way way more than 21, 21 is just an average - I'll bet there were times you had many times more than that trying to be active) try to be active on a small four core machine?
I'd suggest lowering your connection pool to about 16 from its current setting of well over 100.
watch this for some evidence that what I'm saying is true: 
http://www.youtube.com/watch?v=xNDnVOCdvQ0  
 
 
latch : shared pool event
aliyar, February  13, 2012 - 3:57 pm UTC
 
 
dear Tom,
Thanks a lot for clear explanation. from your reply and youtube session i got the following points
1 ) as we have more active calls ( approx 22 active calls per sec with just 04 cpu core ) we are seeing " latch : shared pool event" and "cursor: mutex S" waits as top 5 waits.  so here we need not to bother about waits, rather heavy load on the system.
2 ) permenent fix is either ask application team to cut down the concurrency to lower value which is acceptable for 04 cpu core   or increase the CPU core to higher value which is acceptable for 22 active calls per sec kind of load
in a netshell , our system performnace came downdue do more load which was more than server capacity
please correct me if i am wrong
again thanks a lot Tom . i have learnt a lot from your site.thanks for such a usefull site for DBA
Thanks
Aliyar 
February  13, 2012 - 4:33 pm UTC 
 
1) not really high load - but lots of concurrent requests on a machine with limited resources.  Consider what happens when you have dozens of users trying to parse at the same time - all needing a latch - a latch held by someone that is currently NOT ON THE CPU.  This is what causes your big waits for these things (coupled with the fact that dozens of sessions are waiting for it at the same time!)
2) or.... you implement a resource manager plan that limits the number of active sessions to N, where N is a reasonable number.
otherwise, yes - you are seeing contention based waits because you are trying to do a lot concurrently (decrease concurrency and waits go away - as evidenced by the fact you were doing MORE with LESS when it was "good").
You would like to queue in the middle tier as queuing on the database will take.... database resources!  If you want to do more in the database, you would use your middle tier as it was designed - like CICS to Tuxedo has been used for decades.  To LIMIT the amount of concurrent work submitted to the databases - to release work to the database in a manner that allows it to reach maximum efficiency. 
 
 
SQL statement not in execution phase,
A reader, April     23, 2012 - 8:48 am UTC
 
 
We have a scenario happening now in production database that a particular SID has locked other sessions.  I can see from v$session using blocking_session attribute.
I tried to trace using dbms_monitor for couple of sessions that are blocked.  I didn't see trace file generating in dump location and when I checked v$session_even, there wasn't any event that was associated to the SID.
I thought the SQL statement is stuck in library cache.  When  I queried v$librarycache view, I found the following:
NAMESPACE                                                              GETS    GETHITS GETHIT_RATIO       PINS    PINHITS PINHIT_RATIO    RELOADS INVALIDATIONS
---------------------------------------------------------------- ---------- ---------- ------------ ---------- ---------- ------------ ---------- -------------
SQL AREA STATS                                                      1071031     129221        12.07    1071031     129221        12.07          0             0
ACCOUNT_STATUS                                                      1223355    1222313        99.91          0          0          100          0             0
SQL AREA BUILD                                                      1078080     256446        23.79          0          0          100          0             0
SQL AREA                                                            8244880    7994569        96.96  285141834  283524257        99.43     242289        182992
I also checked locking in library cache and found thousands of rows with Namespace as SQL AREA BUILD.
I didn't understand this concept.  Could you please explain what SQL AREA BUILD, SQL AREA STATS mean and why such high invalidations for SQL AREA in the above output?
Thanks,
 
April     23, 2012 - 1:30 pm UTC 
 
I tried to trace using dbms_monitor for couple of sessions that are blocked.  I 
didn't see trace file generating in dump location and when I checked 
v$session_even, there wasn't any event that was associated to the SID.,
well, if they are blocked - they are blocked and will be blocked (and hence not really writing anything out to trace) until they become unblocked.
I thought the SQL statement is stuck in library cache.  When  I queried 
v$librarycache view, I found the following:
why - why do you think that, what evidence did you gather to suggest that?  why couldn't it just be "session 1 locked a row that sessions 2, 3, 4, 5, .... are trying to lock" 
 
 
follow up,
A reader, April     23, 2012 - 2:46 pm UTC
 
 
I have no evidence that it got stuck in library cache. You are right - multiple sessions are waiting for the lock to get released.
Well, I checked with the development team.  They migrated from 11.1 to 11.2 recently and started having performance issues. The other difference is, on their older system, the DB was on single instance and now it is 2-node RAC.
The UPDATE statement updates one row since they have primary key attribute in their "where" clause.  The users through web URL access the database and performs the updates.  The chances are very less that multiple users try to update the same invoice ID.  However, the team mentioned the users might close the web server abruptly if they don't see the results quickly.
I also checked the explain plan and it is very simple (INDEX UNIQUE SCAN on the primary key)
Since they are on RAC now, could hash partitioning the Primary key help?
 
April     24, 2012 - 7:31 am UTC 
 
Since they are on RAC now, could hash partitioning the Primary key help?
it sounds like they are going after the same records to me - nothing will help that short of "don't let them go after the same record"
Let me ask you this - are they updating a row they have not already locked.  If so, they are almost surely suffering from "lost updates" (google that up if you are not familiar with it, a very classic database issue).  
Perhaps they should consider using "select for update NOWAIT" or "select for update WAIT <N>" to attempt to lock and inspect the record before updating it - if the record is locked - they will no longer block and they can inform the user that 'hey, the thing is being worked on by someone else'
 
 
 
Question on Parsing
Ankit, August    10, 2012 - 5:13 am UTC
 
 
Hi Tom,
You have mentioned in an earlier followup that: 
a hard parse. It is very very very bad. 
a soft parse. It is simply very very bad.
the absence of a parse, this is the only good parse going. 
Consider an OLTP enviroments with 70-80 different SQLs running daily, catering to different phases of Business Transactions like Order processing, Order Cancellation etc. Each SQL is defined using Bind variables to avoid Hard Parse. A business transaction lifecycle uses some 15 SQL statements for one type of Business Transaction.
In such an enviroment won't it be impossible not to soft parse a SQL again and again as the Business Transaction Lifecycle would repeated a number of times depending upon the no. of the executions leading to repeated Soft parse of the associated SQL?
Hard parse can be removed by using Bind variables but in the above environment where the SQLs need to be run again during the Transaction Life Cycle what can be done to stop/avoid soft parses?
Please forgive my naiveness as I do not have any develpoment experience.
 
August    17, 2012 - 1:42 pm UTC 
 
if you have a method representing a transaction and you KNOW that method will be invoked over and over again
why would you have that method
open
bind
execute
close
a cursor - when it could
if first_time open end if;
bind
execute
????
or, just move the SQL into plsql stored procedures and we'll do that for you. You'll still have them parsing the call to plsql if they won't keep it open - but if the plsql does five sql statements - you'll have reduced the parsing to 20% of what it used to be!!!
plsql keeps them open for you automagically.
jdbc statement caching can keep them open for you automagically.
developers can do it if they think about it. 
 
 
Ankit, August    14, 2012 - 3:31 am UTC
 
 
Hi Tom,
Logged in after 4 days to see no followup on this question.
With all due respect, do you think my question is irrelevent or incorrect?
Thanks,
Ankit 
August    17, 2012 - 2:06 pm UTC 
 
with all due respect, sometimes I travel and spent a lot of time on airplanes, or sleep and things like that.
 
 
 
:)
Ankit, August    21, 2012 - 1:18 am UTC
 
 
Dear Tom,
I understand your hectic schedule, I just thought that my question was irrelevent and you might have deemed the question as absurd and choose not to answer it.
I am really really appreciate and am thankful for all the help you provide on this site.
Thanks again 
 
Infrastructure for large concurrent users
Ankit, September 20, 2012 - 7:42 am UTC
 
 
Hi Tom,
I read your article - 'On Connection Pools, Cursor Differentiation, and Optimal Ordering' in Oracle Magazine edition.
The user problem described is due to a large number of concurrent users trying to access the application which is hosted on a machine 
with 4 CPU cores and once the number of concurent users were reduced the performance increased.
Consider a scenario where the Application is a web-based shopping site like Amazon.com and the database is running on Oracle.
 -- There will be many users ~ 100K users using the application (browsing the product catalogue). Can be considered as READ-ONLY Activity
 -- Some 5K users actually doing transactions ( buying the products from the site), typically OLTP.
In this type of usage and not causing performance issue like Latching etc., a lot of CPU cores would be required since there will be a number of concurrent users for whom if the number
of CPU cores required will be very high, in the above case it would be some 400-600 CPU cores?
For supporting this kind of application is RAC and EXADATA the only solution?
Thanks,
Ankit 
September 26, 2012 - 11:08 am UTC 
 
In this type of usage and not causing performance issue like Latching etc., a 
lot of CPU cores would be required since there will be a number of concurrent 
users for whom if the number
of CPU cores required will be very high, in the above case it would be some 
400-600 CPU cores?
no, it would not be 400-600.
We can do 10's of thousands of transactions per second on a small 12 core machine (revisit those links).  If we do 10's of thousands of transactions *per second* - and you have 100k users (who do some number of transactions per MINUTE at most - if even that)... then think about how many cores you might need.
it is not the size of the user base, it is the rate of transactions.  assuming a click every 10 seconds or so, you'd need 10,000 transactions per second, something you can do on a small machine 
IF you get your connection pool under control and you don't overwhelm the machine trying to do a gazillion things all at once.
it is simple math at the end, forget user counts, get transaction rates - that is what counts.
size the pool based on your resources (you cannot get blood from a stone, you cannot get an extra transaction per second by exceeding the optimum number of connections - in fact you'll LOSE transactions per second by doing that)
 
 
 
library cache wait
Peter Parker, September 28, 2012 - 1:12 pm UTC
 
 
Hello Tom
We've several ETL loads running against our DB, it's a usual warehouse setup, truncate, load data, recompile some packages etc in night and weekend, the next day reports run in business hours. For the last couple of days, the load seems to hang indefintely specially when it's being run in overlapped business hours (that's when the reports are being fethed from discoverer).
When we checked with DBA, they sent us sessions which are running (ACTIVE) which are causing our load to wait forever:
This is what they sent:
Active session holding the library cache lock:
SQL> select sid,substr(event,1,30),wait_time
  2  from v$session_wait
  3  where sid in (select sid from x$kglpn , v$session
  4  where KGLPNHDL in (select p1raw from v$session_wait
  5  where wait_time=0 and event like 'library cache%')
  6  and KGLPNMOD <> 0
  7  and v$session.saddr=x$kglpn.kglpnuse );
  SID SUBSTR(EVENT,1,30)                                                WAIT_TIME
----- ---------------------------------------------------------------- ----------
   52 SQL*Net message from client                                               6
  190 SQL*Net message from client                                              -1
  292 SQL*Net message from client  
                                            -1
Session waiting due to above listed:
SQL> select sid Waiter,  p1raw,
substr(rawtohex(p1),1,30) Handle,
substr(rawtohex(p2),1,30) Pin_addr
from gv$session_wait where wait_time=0 and event like 'library cache%';  2    3    4
    WAITER P1RAW            HANDLE                                       PIN_ADDR
---------- ---------------- -------------------------------------------- ----------------------
        11 070000007E48A4E8 C9332D0411045513384D                         C9332D041104394B6111
        53 070000007C7D0030 C9332D04110437071855                         C9332D04110449501405
       213 070000007E48A4E8 C9332D0411045513384D                         C9332D0411043D5A4339
       220 070000007C7D0030 C9332D04110437071855                         C9332D0411045A5A0749
       253 070000007D81D600 C9332D04110448104151                         C9332D041104583839
       255 070000002ABCDD70 C9332D04105A53343D51                         C9332D041104471F4309
       306 070000007E276AD8 C9332D04110453015119                         C9332D0410570B16460D
       340 070000007E276AD8 C9332D04110453015119                         C9332D0411043E300521
       383 070000002ABCDD70 C9332D04105A53343D51                         C9332D04106048424329My question is:
The sessions which are ACTIVE and shown as holding the locks are a bunch of SELECT statements, why would a SELECT statement hold LIBRARY CACHE LOCK and not let my load go ahead. I'm not getting satisfactory answer after reading around and checking metalink as well, can you please help explain.
Right now we investigate these session and have them killed and load works, but why..?..  
September 28, 2012 - 4:52 pm UTC 
 
sorry, but those sessions are waiting for the client to tell them to do something - sql*net message from client means "we are waiting"
how about your DBA's use ADDM and ash/awr instead of trying to query up x$ views? 
 
 
LIbrary Cache Wait
Peter Parker, September 30, 2012 - 3:39 pm UTC
 
 
The waiting session are listed down (not the one above).
The one you are looking at are holding session which are showing ACTIVE in v$session and sql_id's lead to to SELECT statements.
I'm sure they are causing library cache waits are when we kill those sessions (listed at start of post), the one's waiting (listed at end of post) start working.
My question is why SELECTS are causing library cache waits (one guess was they were being called from procedures/functions which the load is trying to compile). But is there is really any other reason? 
October   08, 2012 - 3:12 pm UTC 
 
if they are in sql net message FROM CLIENT - they are not active.  
are you sure they are reporting 'active'?
and if the wait time is zero - those other guys are not "stuck", they just started waiting??
i'm really not sure what I'm looking at there. 
 
 
CPU cores for supporting high transaction rate
Ankit, October   01, 2012 - 5:51 am UTC
 
 
Hi Tom,
Thanks for the detailed explanation. I have revisited your article and as per that I seem to get an impression that:
Size of connection Pool = 8 * Number of CPU cores
From your article -->
"I see that you had 134 sessions in the database running on a total of 4 CPU cores. Because it is not really possible for 4 CPU cores to allow 134 sessions to be concurrently active, I recommend that you decrease the number of concurrent sessions by reducing the size of your connection pool—radically. Cut your connection pool to something like 32." --> 32 = 8 * 4
"I know that this fewer-does-more suggestion sounds counterintuitive, but I encourage you to watch this narrated Real World Performance video. In this video, you’ll see what happens in a test of a 12-core machine running transactions and decreasing the size of a connection pool from an unreasonable number (in the thousands) to a reasonable number: 96. At 96 connections on this particular machine, the machine was able to do 150 percent the number of transactions per second and took the response time for these transactions from ~100 milliseconds down to ~5 milliseconds." --> 96 = 8 * 12
Coming back to the scenario where we have 10,000 Transactions/second and so the size of connection pool can be 1000 ( not sure if there is any factor for relationship between Transaction/second and Connection Pool size), so the number of CPU cores would be 125 ( 1000 = 8 * 125)
125 CPU Cores seem too high to me considering that you mentioned that 10,000 Transactions/second can be run on a 12 core machine.
Can you please point out the gaps in above analysis.
Thanks,
Ankit
 
October   08, 2012 - 3:19 pm UTC 
 
In reality - the size of connection pool = N * number of cores
where N is a very personal real number greater than zero and almost surely less than 16.  
Yes, N could be less than one, but probably shouldn't be above 16, normally - somewhere between 2 and 8 would be 'best'.
 ( not sure if there is any factor for relationship between Transaction/second and Connection Pool size),
there is, the MORE connections you have over the sweet spot (typically around 2-8*cores), the LESS transactions per second you will achieve.
did you watch the video?  It shows you everything you need to know.
You don't need 125 cores to do 10k transactions per second as long as your transactions are short.  do the math.
If your transaction takes 5ms, a core could in theory do 200 transactions in a second (in a perfect world).  So, 50 cores could do your 10,000 transactions per second.
If your transaction takes about 1ms, then a core could do 1,000 transactions a second (in a perfect world) and you'd need 10 cores.
If that 1ms is partially spent waiting for something, then a single core might be able to do more than 1,000 transactions in a second and you'd need less cores.
 
 
 
Thanks Tom !
Ankit, October   25, 2012 - 6:03 am UTC
 
 
Hi Tom,
I finally watched the video today, I know understand the logic.
Thanks a lot !
 
 
Thanks Tom !
Ankit, October   25, 2012 - 6:03 am UTC
 
 
Hi Tom,
I finally watched the video today, I now understand the logic.
Thanks a lot !
 
 
Oracle text not using binds
Bertran, October   26, 2012 - 1:30 pm UTC
 
 
Hi Tom,
  Searching the net I found this old thread but don't see any answer from you except that "it doesn't happen to you".
  I see in our RAC ( 11.2.0.3.0 ) a lot of blocks from Oracle Text like :
  declare
     cost sys.ODCICost := sys.ODCICost(NULL, NULL, NULL, NULL);
     arg0 VARCHAR2(1) := null;
    begin
      :1 := "CTXSYS"."TEXTOPTSTATS".ODCIStatsIndexCost(
                     sys.ODCIINDEXINFO('GIO_OWNER',
                            'CX_PROV#PROVIDER_NAME',
                            sys.ODCICOLINFOLIST(sys.ODCICOLINFO('GIO_OWNER', 'PROVIDER', '"PROVIDER_NAME"', 'VARCHAR2', NULL, NULL, 0, 0, 0, 0)),
                            NULL,
                            0,
                            0, 0, 0),
                     0.00001403,
                     cost,
                     sys.ODCIQUERYINFO(2, NULL, sys.ODCICOMPQUERYINFO(NULL, NULL)),
                     sys.ODCIPREDINFO('CTXSYS',
                            'CONTAINS',
                            NULL,
                            0),
                     sys.ODCIARGDESCLIST(sys.ODCIARGDESC(3, NULL, NULL, NULL, NULL, NULL, NULL), sys.ODCIARGDESC(5, NULL, NULL, NULL, NULL, NULL, NULL), sys.ODCIARGDESC(2, 'PROVIDER', 'GIO_OWNER', '"PROVIDER_NAME"', NULL, NULL, NULL), sys.ODCIARGDESC(3, NULL, NULL, NULL, NULL, NULL, NULL)),
                     :6,
                     NULL
                     , :7,
                     sys.ODCIENV(:8,:9,:10,:11));
      if cost.CPUCost IS NULL then
        :2 := -1.0;
      else
        :2 := cost.CPUCost;
      end if;
      if cost.IOCost IS NULL then
        :3 := -1.0;
      else
        :3 := cost.IOCost;
      end if;
      if cost.NetworkCost IS NULL then
        :4 := -1.0;
      else
        :4 := cost.NetworkCost;
      end if;
      :5 := cost.IndexCostInfo;
      exception
        when others then
          raise;
    end;
  Do you know why Oracle Text is not using binds ? Looking at the blocks in memory the only difference seems to be the parameter "sel" in "CTXSYS"."TEXTOPTSTATS".ODCIStatsIndexCost ( 0.00001403 in the example ).
Thanks in advance,
Bertran. 
October   28, 2012 - 11:15 pm UTC 
 
that is using binds, :1, :2, ... - they are binds.
how many of these blocks do you have that only differ by "SEL" - that could be an oversight (in which case you'd have to open an SR with support)
but this statement is definitely using binds. 
 
 
Oracle text not using binds... more info
Bertran Saragusti, October   29, 2012 - 7:23 am UTC
 
 
Tom,
  I do know it is using "some" binds. What I'm concerned about is the ones not being binded.
  We have this "call distribution" :
select inst_id,count(1) num_entries, sum(sharable_mem) sum_shar_mem
from gv$sqlarea
where sql_text like '%ODCIStatsIndexCost%'
and command_type=47
group by inst_id
order by 1;
INST_ID NUM_ENTRIES SUM_SHAR_MEM
1 570 37357952
2 348 25585205
3 223 14671841
4 345 20356261
  Maybe this is not a big issue to make a fuzz about, but I was just curious why Oracle do not bind all the parameters it uses in one of its own products.
Thanks,
Bertran. 
October   29, 2012 - 7:39 am UTC 
 
how many different copies are you seeing?
sometimes we (we being the collective we - all of us, you - me - them) do not bind something *on purpose* - we want a different (or we want the ability to have a different) plan because of the different value.
so - what we need to determine is - is this a problem, is this flooding the sharedd pool - or is it the desired side effect of a programmer purposely NOT BINDING a specific attribute because it leads to a small set of really good plans.
for example, if I had a skewed column that had say 50 or less distinct values - I might "on purpose" not bind against that column in order to get the best plan.  
you said "it is not using binds" - but it is
you said "a lot" - but I have no idea what "a lot" is 
please quantify 
 
 
concurrency
A Reader, April     08, 2013 - 3:32 pm UTC
 
 
Hi Tom,
Library cache contention - Concurrency
DB version : 10.2.0.4
Summary:
issue : 
a) database load ( cpu) go high 0% IDLE and   load as high as worst on DB  host, when number of hits from application to db increases.
b) we see DB not able to accept no connections
c) no issue DB listener
Observations:
a) AWR is scary
b) Session waiting on latch is too too scary
c) Isuses seen when more load on applciation .. hence more active sessiosn.
Root cause - as per our analysis
a) Excessive parsing
b) Special SQL_ID running on behalf of someone... 2hbdag3dfzj9u  -- we have seen people hunting for SQL_TEXT for this SQL_ID
actually this is a cursor not sql it refres to table_1_ff_159_0_0_0
c) we have seen excessive calls to one application procedure ( pkg_sess_role ) which in turn does many things and does 'set role <role_name> ' many times.
d) DB level Audting is enabled and these set role is logged into AUD$.. ADU$ is having a CLOB column... and we suspect table_1_ff_159_0_0_0 is a child cursor which is related with 
this ADD$... 
We know concurrency issue is ( should be) resolved at applciation level.. but we see role of AUD$ and child curors for 2hbdag3dfzj9u - table_1_ff_159_0_0_0 
ady0t9s6h5x5n -  table_1_ff_154_0_0_0
Load Profile
~~~~~~~~~~~~                            Per Second       Per Transaction
                                   ---------------       ---------------
                  Redo size:            476,983.24             57,112.89
              Logical reads:             72,541.85              8,686.00
              Block changes:              2,409.76                288.54
             Physical reads:                270.08                 32.34
            Physical writes:                127.94                 15.32
                 User calls:                854.40                102.30
                     Parses:                557.59                 66.76
                Hard parses:                  1.17                  0.14
                      Sorts:                174.12                 20.85
                     Logons:                  0.30                  0.04
                   Executes:              4,055.11                485.55
               Transactions:                  8.35
Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
latch: library cache                 47,588     180,599   3795   41.9 Concurrenc
cursor: pin S                    50,096,103      63,829      1   14.8      Other
latch: library cache lock            50,437      28,447    564    6.6 Concurrenc
CPU time                                         27,485           6.4
latch: cache buffers chains         161,600      16,543    102    3.8 Concurrenc
SQL ordered by Elapsed Time  
  Elapsed      CPU                  Elap per  % Total
  Time (s)   Time (s)  Executions   Exec (s)  DB Time    SQL Id
---------- ---------- ------------ ---------- ------- -------------
   183,760      5,469          732      251.0    42.7 ad4t1g35gz0pd
BEGIN pkg_sess_role.proc1( :1, :2, :3, :4, :5, :6 ,:7); END;
-- Tanel's Latchprof... to get who is messing up
SQL> get checklatch
  1  set linesize 900
  2  spool latch1.lst
  3  @latchprof name,sqlid % "library cache" 10000
  4* spool off
SQL> get latchprof
  1  DEF _lhp_what="&1"
  2  DEF _lhp_sid="&2"
  3  DEF _lhp_name="&3"
  4  DEF _lhp_samples="&4"
  5  COL name FOR A35 TRUNCATE
  6  COL latchprof_total_ms HEAD "Held ms" FOR 999999.999
  7  COL latchprof_pct_total_samples head "Held %" format 999.99
  8  COL latchprof_avg_ms HEAD "Avg hold ms" FOR 999.999
  9  COL dist_samples HEAD Gets
 10  COL total_samples HEAD Held
 11  BREAK ON lhp_name SKIP 1
 12  DEF _IF_ORA_10_OR_HIGHER="--"
 13  PROMPT
 14  PROMPT
 15  COL latchprof_oraversion NOPRINT NEW_VALUE _IF_ORA_10_OR_HIGHER
 16  SET TERMOUT OFF
 17  SELECT DECODE(SUBSTR(BANNER, INSTR(BANNER, 'Release ')+8,1), 1, '', '--') latchprof_oraversion
 18  FROM v$version WHERE ROWNUM=1;
 19  SET TERMOUT ON
 20  WITH
 21      t1 AS (SELECT hsecs FROM v$timer),
 22      samples AS (
 23          SELECT /*+ ORDERED USE_NL(l) USE_NL(s) USE_NL(l.gv$latchholder.x$ksuprlat) NO_TRANSFORM_DISTINCT_AGG  */
 24              &_lhp_what
 25            &_IF_ORA_10_OR_HIGHER , COUNT(DISTINCT gets)      dist_samples
 26            , COUNT(*)                    total_samples
 27            , COUNT(*) / &_lhp_samples    total_samples_pct
 28          FROM
 29              (SELECT /*+ NO_MERGE */ 1 FROM DUAL CONNECT BY LEVEL <= &_lhp_samples) s,
 30              v$latchholder l,
 31              (SELECT
 32                      sid                                     indx
 33                    , sql_hash_value                          sqlhash
 34                    , sql_address                             sqladdr
 35                    &_IF_ORA_10_OR_HIGHER , sql_child_number  sqlchild
 36                    &_IF_ORA_10_OR_HIGHER , sql_id            sqlid
 37               FROM v$session) s
 38          WHERE
 39              l.sid LIKE '&_lhp_sid'
 40          AND (LOWER(l.name) LIKE LOWER('%&_lhp_name%') OR LOWER(RAWTOHEX(l.laddr)) LIKE LOWER('%&_lhp_name%'))
 41          AND l.sid = s.indx
 42          GROUP BY
 43              &_lhp_what
 44          ORDER BY
 45              total_samples DESC
 46      ),
 47      t2 AS (SELECT hsecs FROM v$timer)
 48  SELECT /*+ ORDERED */
 49      &_lhp_what
 50    , s.total_samples
 51    &_IF_ORA_10_OR_HIGHER , s.dist_samples
 52    --  , s.total_samples_pct
 53    , s.total_samples / &_lhp_samples * 100 latchprof_pct_total_samples
 54    , (t2.hsecs - t1.hsecs) * 10 * s.total_samples / &_lhp_samples latchprof_total_ms
 55    --   s.dist_events,
 56    &_IF_ORA_10_OR_HIGHER , (t2.hsecs - t1.hsecs) * 10 * s.total_samples / dist_samples / &_lhp_samples latchprof_avg_ms
 57    FROM
 58      t1,
 59      samples s,
 60      t2
 61    -- WHERE ROWNUM <= 30
 62  /
 63* COL name CLEAR
18:11:17 SQL> @checklatch
NAME                                SQLID               Held       Gets  Held %     Held ms Avg hold ms
----------------------------------- ------------- ---------- ---------- ------- ----------- -----------
library cache                       ad4t1g35gz0pd       6345         31   63.45   78665.310    ########
library cache lock                  ady0t9s6h5x5n       1135       1127   11.35   14416.770      12.792------<< pseudo cursor
library cache                       ady0t9s6h5x5n        583        360    5.83    7405.266      20.570------<< pseudo cursor
library cache                                            273         55    2.73    3467.646      63.048----?
library cache pin                                         26         25     .26     330.252      13.210
library cache                       fcn2tzk76bpqg         25         12     .25     317.550      26.463
 
18:16:20 SQL> select sql_text from v$sql  where sql_id='ad4t1g35gz0pd';
SQL_TEXT
---------------------------------------------------------------------------------------------------------
BEGIN pkg_sess_role.proc1( :1, :2, :3, :4, :5, :6 ,:7); END;
 
SQL> SELECT *
  2    FROM (  SELECT datatype_string, name, position
  3              FROM dba_hist_sqlbind
  4             WHERE sql_id = 'ad4t1g35gz0pd'
  5          ORDER BY snap_id DESC, position ASC)
  6   WHERE ROWNUM <= 7;
DATATYPE_STRING NAME                             POSITION
--------------- ------------------------------ ----------
VARCHAR2(32512) :1                                      1
NESTED TABLE    :2                                      2
RAW(32512)      :3                                      3
VARCHAR2(32512) :4                                      4
VARCHAR2(32512) :5                                      5
VARCHAR2(32512) :6                                      6
VARCHAR2(32512) :7                                      7
NESTED TABLE is causes this…
And the other SQL ID
SQL> select distinct sql_text, count(*)   from v$open_cursor where sql_id = 'ady0t9s6h5x5n' group by sql_text;
SQL_TEXT                                                       COUNT(*)
------------------------------------------------------------ ----------
table_1_ff_154_0_0_0                                                307
--- Pseudo cursors
What  it is referring today….
SQL> SELECT owner,
  2         object_name,
  3         object_id,
  4         object_type
  5    FROM dba_objects
  6   WHERE object_id = TO_NUMBER ('154', 'xxx');
OWNER                          OBJECT_NAME                     OBJECT_ID OBJECT_TYPE
------------------------------ ------------------------------ ---------- -------------------
SYS                            KOTTB$                                340 TABLE
Further 
PACKAGE BODY pkg_sess_role AS
…
…
PROCEDURE proc1(
               I_USERDN       IN      VARCHAR2,
               I_ROLELIST     IN      T_SESS_ROLELIST,
               I_LOCALE       IN      LONG RAW,
               I_TIMEZONE     IN      VARCHAR2,
               I_ERRORNUMBERSACTIVATED IN VARCHAR2,
               I_USERASSOTICKET IN VARCHAR2,        
SQL> SELECT u.NAME user_name, o.NAME object_name,
  2  CASE
  3  WHEN o.type# = 13
  4  THEN 'TYPE'
  5  WHEN o.type# = 14
  6  THEN 'TYPE BODY'
  7  ELSE 'UNKNOWN'
  8  END AS obj_type
  9  FROM SYS.kottd$ kd, SYS.obj$ o, SYS.user$ u
 10  WHERE o.oid$ = kd.sys_nc_oid$
 11  AND u.user# = o.owner#
 12  AND o.NAME = 'T_SESS_ROLELIST';
USER_NAME                      OBJECT_NAME                    OBJ_TYPE
------------------------------ ------------------------------ --------------------------------
USERA                         T_SESS_ROLELIST             TYPE
      
ady0t9s6h5x5n -- pseudo cursor...
Further,
1.we asked Oracle ( 
I have raised SR 3-7011120501.  ) if pseudo cursors contention is bug and confirmed it  a bug.
bug 7648406 exists also for 10.2.0.4
2. And to add to it  
open_cursors =32000    !
and
session_cached_cursors = 12000  !
these two parameters are a must candidate to revisit.
Questions
a) Upto what extent this bug would fix the issue? I feel it should resolve .. as nested tables data types in package call and CLOB columns in AUD$  are involved 
b) Actual bug is in the code...PLSQL code.? I am going to re-read  your Effective Oracle By design and chaptor -effective PLSQL. tonight
PROCEDURE proc1(
               I_USERDN       IN      VARCHAR2,
               I_ROLELIST     IN      T_SESS_ROLELIST,----- nested table type... leading  pseudo cursors..
               I_LOCALE       IN      LONG RAW,
               I_TIMEZONE     IN      VARCHAR2,
               I_ERRORNUMBERSACTIVATED IN VARCHAR2,
               I_USERASSOTICKET IN VARCHAR2,        
               I_ASMSESSIONTICKET IN VARCHAR2) IS
        FN CONSTANT VARCHAR2(30)  := 'proc1';
    BEGIN
        IF pkg_log.HASACTIVELOGGER(GRP,PKG,FN,pkg_log.LEVEL_ENTRY) THEN
          DECLARE 
            V_BUFFER VARCHAR2(32512) := pkg_log.FORMATBEGINTABLE('i_rolelist','T_SESS_ROLELIST');
          BEGIN
            IF I_ROLELIST IS NOT NULL THEN ----code from this line onwards looks disaster to me....
              FOR I IN 1..I_ROLELIST.COUNT LOOP
                V_BUFFER := pkg_log.CONCAT(V_BUFFER,
                  pkg_log.FORMATBEGINOBJECT('['||I||']','o_session_rolelist'), --- specifically this one... causing it to die for library cache latch?
                  pkg_log.FORMATSTRINGPARAMETER('role',I_ROLELIST(I).ROLE),
                  pkg_log.FORMATENDOBJECT);
              END LOOP;
            END IF;
            V_BUFFER := pkg_log.CONCAT(V_BUFFER, pkg_log.FORMATENDTABLE);
          
            pkg_log.ENTRY(GRP,PKG,FN,pkg_log.CONCAT(
              pkg_log.FORMATSTRINGPARAMETER('i_userdn',I_USERDN),
              V_BUFFER,
              pkg_log.FORMATSTRINGPARAMETER('i_locale','[LONG RAW]'),
              pkg_log.FORMATSTRINGPARAMETER('i_timezone',I_TIMEZONE),
              pkg_log.FORMATSTRINGPARAMETER('i_errornumbersactivated',I_ERRORNUMBERSACTIVATED),
              pkg_log.FORMATSTRINGPARAMETER('i_USERAssoticket',I_USERASSOTICKET),
              pkg_log.FORMATSTRINGPARAMETER('i_asmsessionticket',I_ASMSESSIONTICKET)
            ));
          END;
        END IF;
        
        SETROLES(
            pkg_sessioncontext.proc1(I_USERDN, I_ROLELIST, I_LOCALE, I_TIMEZONE,I_ERRORNUMBERSACTIVATED,I_USERASSOTICKET,I_ASMSESSIONTICKET));
        pkg_log.EXIT(GRP,PKG,FN,NULL);
    END; 
is it because of for loop above excessive parsing ?
 
 
thanks 
 
 
 
April     22, 2013 - 2:26 pm UTC 
 
".... AWR is scary ... "
?????????????????????????????? I have no idea how to even parse that statement.
before I look at this, how many connections do you have (count(*) from v$session) and how many cores do you have ( not sockets, not threads - actual cores) 
 
 
..concurrency   
A Reader, April     08, 2013 - 3:43 pm UTC
 
 
Tom
AWR snip is  taken from 1 hr AWR
no of cpu cores 32 
 
..concurrency    contd
A Reader, May       04, 2013 - 10:42 pm UTC
 
 
Thanks Tom
Please find the details below.
 
1. how many connections do you have (count(*) from v$session)  ?
we have total  03 databases running on the same host.
1.1 count from v$session for the database in discussion above 
 during normal period  ~ 800
 during problem period( when we have concurrency waits) ~1200
1.2 count from v$session for other 02 databases which are running on the same host are ~1800 and ~1300
2.  how many cores do you have ( not sockets, not threads - actual cores) 
$ psrinfo -p
16
16 cores.
regards
 
May       06, 2013 - 7:21 pm UTC 
 
this video was made for you:
 http://tinyurl.com/RWP-OLTP-CONNECTIONS are you KIDDING!!!! 16 poor little cores.  16 teeny tiny little cores.
and 3,000 to 5,000 connections!!!!! 
are you *kidding*?
who thought that was a good idea???? 
 
 
..concurrency contd   
A Reader, May       07, 2013 - 3:29 am UTC
 
 
You are right Tom,
:)
it is poor design issue . and is being worked out.
:(
In the meantime, the need of the hour is how  to live with it till it is fixed/ re-desinged.
Calls to the package has added  more to the existing problem.
i.e. Whenever there are more concurrent calls to the package we concurrency related wait events ( library cache latch) are the top most. 
-- package.procedure deatails with my observation/comments 
PROCEDURE proc1(
               I_USERDN       IN      VARCHAR2,
               I_ROLELIST     IN      T_SESS_ROLELIST,----- nested table type... leading  pseudo 
cursors..
               I_LOCALE       IN      LONG RAW,
               I_TIMEZONE     IN      VARCHAR2,
               I_ERRORNUMBERSACTIVATED IN VARCHAR2,
               I_USERASSOTICKET IN VARCHAR2,        
               I_ASMSESSIONTICKET IN VARCHAR2) IS
        FN CONSTANT VARCHAR2(30)  := 'proc1';
    BEGIN
        IF pkg_log.HASACTIVELOGGER(GRP,PKG,FN,pkg_log.LEVEL_ENTRY) THEN
          DECLARE 
            V_BUFFER VARCHAR2(32512) := pkg_log.FORMATBEGINTABLE('i_rolelist','T_SESS_ROLELIST');
          BEGIN
            IF I_ROLELIST IS NOT NULL THEN ----code from this line onwards looks disaster to me....
              FOR I IN 1..I_ROLELIST.COUNT LOOP
                V_BUFFER := pkg_log.CONCAT(V_BUFFER,
                  pkg_log.FORMATBEGINOBJECT('['||I||']','o_session_rolelist'), --- specifically 
this one... causing it to die for library cache latch?
                  pkg_log.FORMATSTRINGPARAMETER('role',I_ROLELIST(I).ROLE),
                  pkg_log.FORMATENDOBJECT);
              END LOOP;
            END IF;
            V_BUFFER := pkg_log.CONCAT(V_BUFFER, pkg_log.FORMATENDTABLE);
          
            pkg_log.ENTRY(GRP,PKG,FN,pkg_log.CONCAT(
              pkg_log.FORMATSTRINGPARAMETER('i_userdn',I_USERDN),
              V_BUFFER,
              pkg_log.FORMATSTRINGPARAMETER('i_locale','[LONG RAW]'),
              pkg_log.FORMATSTRINGPARAMETER('i_timezone',I_TIMEZONE),
              pkg_log.FORMATSTRINGPARAMETER('i_errornumbersactivated',I_ERRORNUMBERSACTIVATED),
              pkg_log.FORMATSTRINGPARAMETER('i_USERAssoticket',I_USERASSOTICKET),
              pkg_log.FORMATSTRINGPARAMETER('i_asmsessionticket',I_ASMSESSIONTICKET)
            ));
          END;
        END IF;
        
        SETROLES(
            pkg_sessioncontext.proc1(I_USERDN, I_ROLELIST, I_LOCALE, 
I_TIMEZONE,I_ERRORNUMBERSACTIVATED,I_USERASSOTICKET,I_ASMSESSIONTICKET));
        pkg_log.EXIT(GRP,PKG,FN,NULL);
    END; 
Questions
a) your inputs on  above procedure code in view of library cache latch issue.( evey minute 1 or 2 calls to above package we dont have issues.. but of the number of calls goes beyond 20 .. we started seeing concurrency related issue... worsen by 
Psuedo cursor bug 7648406 Child cursors not shared for "table_..." cursors (that show as "SQL Text Not Available") when NLS_LENGTH_SEMANTICS = CHAR
 ) 
b) whether not binding I in loop below is the issue?
 FOR I IN 1..I_ROLELIST.COUNT LOOP
c) Unable to get the bind values for the given procedure call
select * from dba_hist_sqlbind where sql_id=<sqlId>;
WAS_CAPTURED  column is NO in the output?
regards
 
May       07, 2013 - 2:54 pm UTC 
 
cut back the size of your connection pool.  no design required, just common sense and math (divide number of cores into sessions, see big number, know that is bad)
a) I cannot comment on a snippet of code that calls a gazillion other things, without knowledge of what is trying to be accomplished (what the goal is), why the code even exists.  (and you cannot really supply all of that here....  way too much)
I don't know how a table_.... cursor would be impacting this, it doesn't seem to be doing any lob.
b) I don't see any dynamic sql, hence you are binding everywhere possible since static sql in plsql can only bind inputs.
c) you don't show how it was called - and we don't capture all or even most in there.  and that is a snapshot of v$sql_bind_capature which only: 
http://docs.oracle.com/cd/B19306_01/server.102/b14237/dynviews_2114.htm ... One of the bind values used for the bind variable during a past execution of its associated SQL statement. Bind values are not always captured for this view. Bind values are displayed by this view only when the type of the bind variable is simple (this excludes LONG, LOB, and ADT datatypes) and when the bind variable is used in the WHERE or HAVING clauses of the SQL statement. ... 
 
 
..concurrency contd   
A Reader, May       14, 2013 - 5:07 am UTC
 
 
Hello Tom,
Thanks for your time.
regarding your question
 
............I don't know how a table_.... cursor would be impacting this, it doesn't seem to be doing any lob. 
In our scenario table_... cursor is due to    NESTED TABLE  data type..  
details follows.
SQL_ID for this package.procedure  ( pkg_sess_role.proc1 )  in discussion is - ad4t1g35gz0pd
18:16:20 SQL> select sql_text from v$sql  where sql_id='ad4t1g35gz0pd';
SQL_TEXT
----------------------------------------------------------------------------------------------------
-----
BEGIN pkg_sess_role.proc1( :1, :2, :3, :4, :5, :6 ,:7); END;
 
SQL> SELECT *
  2    FROM (  SELECT datatype_string, name, position
  3              FROM dba_hist_sqlbind
  4             WHERE sql_id = 'ad4t1g35gz0pd'
  5          ORDER BY snap_id DESC, position ASC)
  6   WHERE ROWNUM <= 7;
DATATYPE_STRING NAME                             POSITION
--------------- ------------------------------ ----------
VARCHAR2(32512) :1                                      1
NESTED TABLE    :2                                      2
RAW(32512)      :3                                      3
VARCHAR2(32512) :4                                      4
VARCHAR2(32512) :5                                      5
VARCHAR2(32512) :6                                      6
VARCHAR2(32512) :7                                      7
NESTED TABLE is causing this…
other SQL ID
SQL> select distinct sql_text, count(*)   from v$open_cursor where sql_id = 'ady0t9s6h5x5n' group 
by sql_text;
SQL_TEXT                                                       COUNT(*)
------------------------------------------------------------ ----------
table_1_ff_154_0_0_0                                                307
--- Pseudo cursors
What  it is referring today….
SQL> SELECT owner,
  2         object_name,
  3         object_id,
  4         object_type
  5    FROM dba_objects
  6   WHERE object_id = TO_NUMBER ('154', 'xxx');
OWNER                          OBJECT_NAME                     OBJECT_ID OBJECT_TYPE
------------------------------ ------------------------------ ---------- -------------------
SYS                            KOTTB$                                340 TABLE
Further 
PACKAGE BODY pkg_sess_role AS
…
…
PROCEDURE proc1(
               I_USERDN       IN      VARCHAR2,
               I_ROLELIST     IN      T_SESS_ROLELIST,  -----<<<<<<<<<<<<<< Nested Table DATA TYPE
               I_LOCALE       IN      LONG RAW,
               I_TIMEZONE     IN      VARCHAR2,
               I_ERRORNUMBERSACTIVATED IN VARCHAR2,
               I_USERASSOTICKET IN VARCHAR2,        
SQL> SELECT u.NAME user_name, o.NAME object_name,
  2  CASE
  3  WHEN o.type# = 13
  4  THEN 'TYPE'
  5  WHEN o.type# = 14
  6  THEN 'TYPE BODY'
  7  ELSE 'UNKNOWN'
  8  END AS obj_type
  9  FROM SYS.kottd$ kd, SYS.obj$ o, SYS.user$ u
 10  WHERE o.oid$ = kd.sys_nc_oid$
 11  AND u.user# = o.owner#
 12  AND o.NAME = 'T_SESS_ROLELIST';
USER_NAME                      OBJECT_NAME                    OBJ_TYPE
------------------------------ ------------------------------ --------------------------------
USERA                         T_SESS_ROLELIST                 TYPE
               
ady0t9s6h5x5n -- pseudo cursor...
bug 7648406 information 
Abstract : Child cursors not shared for "table_..." cursors (that show as "SQL Text Not Available") when NLS_LENGTH_SEMANTICS = CHAR
we have 
13:48:14 SQL> show parameter nls_length_
NAME_COL_PLUS_SHOW_PARAM       TYPE                             VALUE_COL_PLUS_SHOW_PARAM
------------------------------ -------------------------------- ------------------------------
nls_length_semantics           string                           CHAR
 
and DB version 10.2.0.4
13:48:17 SQL > select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Solaris: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
bottomline - using NESTED table data type also cause table_.... cursor [ CLOB  data type also does this ] 
   Here are the stats , during problem window ,
   at one point in time t1   
     100 concurrent calls to package pkg_sess_role.proc1 
     300 psuedo cursor calls.
     problem persists
   later at some point in time t2 
     10  concurrent calls to package pkg_sess_role.proc1 ( concurrent calls reduced   due to varying application  load )
     300 psuedo cursor calls.
     problem persists
   later at some point in time t3 
     2  concurrent calls to package pkg_sess_role.proc1 ( concurrent calls reduced   due to varying application  load )
     200 psuedo cursor calls.
     problem persists 
   later at some point in time t4 
     0   concurrent calls to package pkg_sess_role.proc1 ( concurrent calls reduced to zero  due to varying application  load )
     200 psuedo cursor calls.
     problem persists
   later at some point in time t5 
     0   concurrent calls to package pkg_sess_role.proc1  
     3 psuedo cursor calls.
     problem GONE. DB load came down. everything ok
question
a) as we see  huge library cache contention against the package  ( pkg_sess_role.proc1 ), whether contention is contributed majorily due to  table_... cursors?
b) if above ( a) is TRUE then it is only the  non sharing of psuedo cursor is the cause of contention here.. and we need not to fix anything on package from  parsing point of view and just bug fix 7648406   would help?
c) this is again question similar to (a) ,  whether library cache latch waits would get accumulated if there are calls to table_... cursor , if such psuedo cursor calls calls are made on behalf of the  package ( pkg_sess_role.proc1 in our case)?
  
 
May       14, 2013 - 12:27 pm UTC 
 
16 cores
100 things trying to be concurrently active
do the math
the cause of your contention is 100 things trying to use 16 resources.  Say a latch holder gets kicked off the CPU holding a latch while the other 99 try to get it... think about what happens.
back off the size of your connection pool, this is not a design detail, this is a configuration change.
I can instantly cut your waits by 50%, cut your connection pool in half.  You want the waits to go away?  have a reasonable number of concurrent sessions on your 16 core machine.
you have more active sessions that are dying for cpu than that machine can handle.  At least benchmark this in your test environment... 
 
 
remove_constants simpler with regexp
John-Paul Busick, May       30, 2013 - 10:04 pm UTC
 
 
The reason for using bind variables has finally been nailed home after trying this function on our test DB and finding 3749 different sql_text's for the exact same statement. All because the code was inserting variables as literals into the sql before executing to get the desired result.
It took me a few minutes to get what the remove_constants function was doing with each char in the loop, but once I did I thought it might be easier to read or expandable using regexp_replace like this:
CREATE OR REPLACE FUNCTION remove_constants (p_query IN VARCHAR2)
   RETURN VARCHAR2
AS
   l_query       LONG;
   l_char        VARCHAR2 (1);
   l_in_quotes   BOOLEAN DEFAULT FALSE;
BEGIN
--this regexp pattern matches a single quote then all none single quote
-- characters until a closing single quote and replaces it with the uniform 
-- hash symbol
   l_query := REGEXP_REPLACE (p_query, '[''][^'']+['']', '''#''');
   
--this will replace any numeric values not specifically preceded by a colon 
-- with the at symbol (this may change numbers inside SQL column names
-- and stuff but since we are just trying to eliminate differences due to none
-- bound literals this should still give us the count we want for similar 
-- sql_text values that are not binding variables correctly)
   l_query := REGEXP_REPLACE (l_query, '[^:][0-9]+', '@');
   
--this just consolidates spaces by matching any space and every space that 
-- follows it with a single space
   l_query := REGEXP_REPLACE (l_query, '[ ]+', ' ');
   
   RETURN UPPER (l_query);
END;
/
 
 
remove_constants query without function
John-Paul Busick, June      05, 2013 - 2:05 pm UTC
 
 
I didn't have access to create a function in the database I was trying to help tune so I tried the regexp_replace directly in a query instead of in a function and it worked out for me so I thought if anyone else was in a similar boat I would post the statement:
  SELECT REGEXP_REPLACE (
            REGEXP_REPLACE (
               REGEXP_REPLACE (sql_text, '[''][^'']+['']', '''#''')
               , '[^:][0-9]+', '@'),
            '[ ]+', ' '),
         COUNT (*)
    FROM v$sqlarea
GROUP BY REGEXP_REPLACE (
            REGEXP_REPLACE (
               REGEXP_REPLACE (sql_text, '[''][^'']+['']', '''#''')
               , '[^:][0-9]+', '@'),
            '[ ]+', ' ')
  HAVING COUNT (*) > 100
ORDER BY 2 DESC;