Clarify
A reader, September 27, 2001 - 10:38 am UTC
September 27, 2001 - 2:37 pm UTC
The sql you see there is what is currently in the shared pool. All of the sql you executed since the beginning of your session MAY or MAY NOT be in there still. Even if it all IS -- the fact that YOU executed is NOT tracked.
There will be one copy of "select * from emp" typically in the shared pool. 1,000,000 sessions may each have executed it 5 times. We do not track who executed and what sort of buffer reads they have.
If you are currently executing a statement -- it will be in the shared pool. Hence we can get the ACTIVE sql -- but not sql you executed 5 minutes ago.
v$sql and related views are just peeking at the memory of the SGA. The criteria for being in there is someone parsed you. The criteria for getting out is that no one has used you for a while.
v$sqlarea is an aggregate view, v$sql is not. duplicates (child cursors) are removed in v$$sqlarea (you should use v$sql for casual queries for this reason -- more efficient)
It is not really true that count(*) in v$sqlarea is count of queries in the shared pool, its the count of the distinct query texts in the shared pool. That is
"select * FROM T"
might be in the shared pool two times because the user mike, who owns mike.t, submitted and the user tom, who owns tom.t, submitted it and its really TWO different queries with the same text.
A Reader
A Reader, September 28, 2001 - 12:54 am UTC
<quote>
v$sqlarea is an aggregate view, v$sql is not. duplicates (child cursors) are removed in v$$sqlarea (you should use v$sql for casual queries for this reason -- more efficient)
<quote>
Could you give an example of *duplicates (child cursors)"
Thanks
September 28, 2001 - 6:56 am UTC
Sure, I have two users OPS$TKYTE and SCOTT. they both have EMP tables. They both ran some queries. When I look in v$sqlarea:
ops$tkyte@ORA817DEV.US.ORACLE.COM> select sql_text, version_count from v$sqlarea where sql_text like 'select * from emp%';
SQL_TEXT VERSION_COUNT
---------------------------------------- -------------
select * from emp 1
select * from emp e1 2
select * from emp e2 2
select * from emp, dept where emp.deptno 1
= dept.deptno
select * from emp@ora815.us.oracle.com 1
I see 2 versions of select * from emp e1, select * from emp e2. I only see the query once but I know there are two versions. So, I goto v$sql:
ops$tkyte@ORA817DEV.US.ORACLE.COM> select sql_text, parsing_user_id, parsing_schema_id from v$sql where sql_text like 'select * from emp%';
SQL_TEXT PARSING_USER_ID PARSING_SCHEMA_ID
---------------------------------------- --------------- -----------------
select * from emp 0 0
select * from emp, dept where emp.deptno 28 28
= dept.deptno
select * from emp e2 28 28
select * from emp e2 0 0
select * from emp@ora815.us.oracle.com 28 28
select * from emp e1 28 28
select * from emp e1 0 0
7 rows selected.
And I can see why. The select * from emp e2 queries where parsed by different users, with different effective (parsing schema id) ids. They are the same text -- totally different queries.
READER
Reader, September 28, 2001 - 12:55 pm UTC
Given "PARSING_USER_ID PARSING_SCHEMA_ID" be the same
and ivalidations = 0, what other causes are for multiple versions
Thanks
September 28, 2001 - 2:08 pm UTC
session level settings play into this hugely
o different optimizer goals
o different sort area sizes
o different optimizer_* parameters
o and so on.
each of those will cause a different plan to be generated (hence child cursors)
how to see actual bind variable values
P, March 25, 2003 - 6:11 pm UTC
hi tom,
is there a way to see actual values for bind variables instead of :1 :2 in v$sqlarea/v$sql views?
March 25, 2003 - 8:42 pm UTC
no, there is not. they are in the UGA of the session which is normally in the PGA memory only.
remember -- v$sql/sqlsarea represent SHARED stuff -- there could be thousands of :1 values for any single statement in there.
Excellent!
A Reader, March 25, 2003 - 9:48 pm UTC
My unserstanding is that each session in dedicated server architecture will have its own UGA/PGA and it is not part of SGA. My question related to your comment above "no, there is not. they are in the UGA of the session which is normally in the PGA memory only." If the values for bind variables are in UGA, why can't a current session see the value of bind variables that are used in that session. Is there a way to see it at all? Thanks.
March 26, 2003 - 7:23 am UTC
a current session can, v$sql_bind_data, v$sql_bind_metadata, session specific v$ views.
Truncated SQL_TEXT
Fred Shimaya, August 13, 2003 - 9:32 pm UTC
Tom,
I am interested in looking at very long statements in v$sql, but most of those are truncated. Thus I can't see if bind variables were being used. Is there a way to see the whole statement?
Fred
August 13, 2003 - 9:42 pm UTC
v$SQLTEXT_WITH_NEWLINES
thanks a mucho!
Fred Shimaya, August 13, 2003 - 9:54 pm UTC
Senor El Caro,
Gracias por la ayuda!
Auditing SQL
Praveen, August 14, 2003 - 12:17 am UTC
Hi Tom,
Version : Oracle 8.1.7
I am developing an audit trail for our warehouse system. I want to trap the sql statements if user deletes, updates or truncates the table. How to trap the sql's that user is executing. I tried using the following query but always got no rows found.
select distinct substr(sql_text,1,100) IN_TRIGGER into v_sql_text
from v$sql
where address in (select sql_address from v$session
where osuser = sys_context('userenv','os_user')
and status = 'ACTIVE'
)
and sql_text not like '%IN_TRIGGER%'
August 14, 2003 - 7:54 am UTC
you cannot get the text of the query in 8i.
you can in 9i using a trigger -- there is a function provided for doing so.
When was the last time shared pool object was flushed?
Sai, September 22, 2003 - 4:15 pm UTC
Hi Tom,
I would like to know "when was the last time shared pool flushed/aged out any object from the pool".
If I have a job set up to collect snapshot of v$sql every 30 mins, is it safe to assume that none of the sql statements were aged out or flushed out from the shared pool if the first_load_time is less than last 30 mins?
Thanks
September 22, 2003 - 8:09 pm UTC
not safe, the entire entry could "disappear" - the thing being flushed itself could "go away" entirely.
When was the last time shared pool object was flushed?
Sai, September 22, 2003 - 9:34 pm UTC
Hi Tom,
I request you to help me with this question. Why would Oracle flush any object out of shared pool if there are no new sql statements being executed, unless somebody flush out entire shared pool. With this assumption, I thought, Oracle didn't yet flushed any objects out since max(to_date(first_load_time,......')), in other words, the last time Oracle flushed any object could be <= max(to_date(first_load_time,'.....)). Please explain.
Thanks.
September 22, 2003 - 9:47 pm UTC
ops$tkyte@ORA920LAP> create table t ( x int );
Table created.
ops$tkyte@ORA920LAP> select * from t test;
no rows selected
ops$tkyte@ORA920LAP> select first_load_time from v$sql where sql_text = 'select * from t test';
FIRST_LOAD_TIME
-------------------
2003-09-22/21:42:38
ops$tkyte@ORA920LAP> alter table t add y int;
Table altered.
ops$tkyte@ORA920LAP> select * from t test;
no rows selected
ops$tkyte@ORA920LAP> select first_load_time from v$sql where sql_text = 'select * from t test';
FIRST_LOAD_TIME
-------------------
2003-09-22/21:42:38
Ok, so what does this show? well, nothing directly but -- obviously, "select * from t test" was invalidated and then rebuilt -- but the load time didn't change (and I type fast, but not that fast)...
so, what if "select * from t test" took 5 times the amount of space? something might have to go.
it could be that the statements are in v$sql -- but is invalidated -- so not really in the shared pool truly. So, they actually get parsed and loaded up -- flushing other stuff out as well. (statements do not fall out of v$sql when invalidated...)
A reader, September 23, 2003 - 12:23 am UTC
Bind variables etc.
Neil, September 23, 2003 - 7:14 am UTC
The trace analyzer will give you the values of your bind variables. Only retrospectivly, though. Get TRCA.zip from technet...
For Neil
Riaz Shahid, September 23, 2003 - 11:08 am UTC
Neil !
Can you please paste here the link for trca.zip ?
Thanks
September 23, 2003 - 11:40 am UTC
it is actually on metalink.oracle.com, just search for trca.zip and it pops right up
View all the SQLs executed during the day
A reader, February 01, 2005 - 12:39 pm UTC
Hi Tom,
I need to see all the SQLs executed on a DataBase during a day. How can I achieve that?
Also, is that possible to get the parameters passed with the SQLs ? If yes then HOW ?
Could you provide the complete details or I can find it somewhere ?
Thanks
February 01, 2005 - 2:20 pm UTC
dbms_fga would be one way -- you can audit all selects. including the binds.
supplied packages guide
or search this site for dbms_fga.
review
Sven, April 07, 2005 - 10:38 am UTC
Hi Tom,
If I execute the following query:
select sql_text, hash_value, address, VERSION_COUNT, LOADED_VERSIONS,
OPEN_VERSIONS, EXECUTIONS, LOADS, INVALIDATIONS, PARSE_CALLS
from v$sqlarea
where 1=1
order by VERSION_COUNT desc
;
hash_value: 3241877694
address 00000003996B1AE0
VERSION_COUNT 1005
LOADED_VERSIONS 435
OPEN_VERSIONS 0
EXECUTIONS 435
LOADS 1005
INVALIDATIONS 0
PARSE_CALLS 435
I can see for one cursor to have 1005 "VERSION_COUNT". If I take the address of this cursor and execute:
select *
from v$sql_shared_cursor
where kglhdpar = '00000005E3FDE8E0'
and (unbound_cursor = 'Y' or
sql_type_mismatch = 'Y' or
optimizer_mismatch = 'Y' or
outline_mismatch = 'Y' or
stats_row_mismatch = 'Y' or
literal_mismatch = 'Y' or
sec_depth_mismatch = 'Y' or
explain_plan_cursor = 'Y' or
buffered_dml_mismatch = 'Y' or
pdml_env_mismatch = 'Y' or
inst_drtld_mismatch = 'Y' or
slave_qc_mismatch = 'Y' or
typecheck_mismatch = 'Y' or
auth_check_mismatch = 'Y' or
bind_mismatch = 'Y' or
describe_mismatch = 'Y' or
language_mismatch = 'Y' or
translation_mismatch = 'Y' or
row_level_sec_mismatch = 'Y' or
insuff_privs = 'Y' or
insuff_privs_rem = 'Y' or
remote_trans_mismatch = 'Y' or
logminer_session_mismatch = 'Y' or
incomp_ltrl_mismatch = 'Y' or
overlap_time_mismatch = 'Y' or
sql_redirect_mismatch = 'Y' or
mv_query_gen_mismatch = 'Y' or
user_bind_peek_mismatch = 'Y' or
typchk_dep_mismatch = 'Y' or
no_trigger_mismatch = 'Y' or
flashback_cursor = 'Y')
;
I get no result.
Any idea what could be the reason of so high version count?
Thanks.
Sven
April 07, 2005 - 11:37 am UTC
addresses appear different?
review
sven, April 07, 2005 - 12:29 pm UTC
No, the addresses are the same.
For this sql, I did a query on v$sql => address the same, child_address different, module SQL*Plus.
In v$sql_plan they all have separate sql plans (child_number is different) which are the same.
Any thoughts?
April 07, 2005 - 12:45 pm UTC
hash_value: 3241877694
address 00000003996B1AE0 <<<<<<<<<<<<=================
VERSION_COUNT 1005
LOADED_VERSIONS 435
OPEN_VERSIONS 0
EXECUTIONS 435
LOADS 1005
INVALIDATIONS 0
PARSE_CALLS 435
I can see for one cursor to have 1005 "VERSION_COUNT". If I take the address of
this cursor and execute:
select *
from v$sql_shared_cursor
where kglhdpar = '00000005E3FDE8E0' <<<<<<<<<<<<===============
and (unbound_cursor = 'Y' or
look different to me.
review
sven, April 07, 2005 - 1:53 pm UTC
No, sorry for the misunderstanding. I just copied/paste a query for some other object that I have look for.
My intention was to show you which query I have used to obtain the result.
Really, the addresses are the same, the execution plans are the same but as I said in v$sql_plan they all have separate sql plans (child_number is different) generated.
If you like I can post you a results or send you zip with the results.
Sorry once again.
April 07, 2005 - 4:22 pm UTC
querying v$sqlarea
Andrew, October 07, 2005 - 10:23 am UTC
Tom,
For this question, and many others you answer with queries to sys.v$ tables(views).
questions:
1. are v$ tables are memory tables?
2. are queries to v$tables read consistent?
3. If queries to v$tables are read consistent, what is the mechanism that provides the consistency?
4. is it bad to run queries that join v$ tables with non v$tables - queries that might take many seconds to complete?
5. Will long running v$queries takeup resources?
October 07, 2005 - 9:37 pm UTC
1) most are
2) they are documented as not being read consistent
3) see #2
4) v$ tables require in most cases latched access to data structures, that can be a problem (while latched - no modifications, while waiting to be latched - you waiting). queries should be "short" yes.
5) yes, see #4
first load and last load
A reader, February 10, 2006 - 11:23 am UTC
Hi
What is the difference between first_load_time and last_load_time in v$sql?
I have SQL statements which has first_load_time from 1 month ago and last_load_time from 2 days ago. I am puzzled what are they?
February 10, 2006 - 1:18 pm UTC
http://docs.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2113.htm#sthref4036
That has the defintion of each - now, now for the demo ;)
ops$tkyte@ORA10GR2> alter system flush shared_pool;
System altered.
ops$tkyte@ORA10GR2> create table t ( x int );
Table created.
ops$tkyte@ORA10GR2> alter session set optimizer_mode=all_rows;
Session altered.
ops$tkyte@ORA10GR2> select * from t;
no rows selected
ops$tkyte@ORA10GR2> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
ops$tkyte@ORA10GR2> alter session set optimizer_mode=first_rows;
Session altered.
ops$tkyte@ORA10GR2> select * from t;
no rows selected
ops$tkyte@ORA10GR2> select first_load_time, last_load_time from v$sql where sql_text = 'select * from t';
FIRST_LOAD_TIME LAST_LOAD_TIME
------------------- -------------------
2006-02-10/18:00:02 2006-02-10/18:00:02
2006-02-10/18:00:02 2006-02-10/18:00:05
<b>first load time is the load time of the parent. for the first query (which is also the "parent" of all queries that look like select * from t), we have a first_load_time = last_load_time, it was last "optimized" when it was first loaded.
For the second query, 3 seconds later with a different optimizer environment, we have a first_load_time that is consistent (we expect it to be) with the first - it is the parents load time - but the last_load_time, the last time IT was optimized is 3 seconds later.
Let's add an index, to invalidate the existing cursors and causing them to be hard parsed next time:</b>
ops$tkyte@ORA10GR2> create index t_idx on t(x);
Index created.
ops$tkyte@ORA10GR2> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
ops$tkyte@ORA10GR2> alter session set optimizer_mode=all_rows;
Session altered.
ops$tkyte@ORA10GR2> select * from t;
no rows selected
ops$tkyte@ORA10GR2> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
ops$tkyte@ORA10GR2> alter session set optimizer_mode=first_rows;
Session altered.
ops$tkyte@ORA10GR2> select * from t;
no rows selected
ops$tkyte@ORA10GR2> select first_load_time, last_load_time from v$sql where sql_text = 'select * from t';
FIRST_LOAD_TIME LAST_LOAD_TIME
------------------- -------------------
2006-02-10/18:00:02 2006-02-10/18:00:08
2006-02-10/18:00:02 2006-02-10/18:00:11
<b>Now, note that the first_load_time stayed the same - as long as the statement doesn't entirely flush out of the shared pool - it will stay that way.
However, the create index we just did caused the last_load_time for the first query to change - we just re-optimized that plan. Likewise for the second.
We can read that as:
the first time we think we saw 'select * from t' was 2006-02-10/18:00:02. The last time we hard parsed (and hence optimized) the first child cursor was 2006-02-10/18:00:08. The second child cursor was last optimized on 2006-02-10/18:00:11.
</b>
v$sql
Anoop Gupta, March 23, 2006 - 2:31 am UTC
Hi Tom,
I am executing a procedure that contains a set of delete and insert statements.
When I run this procedure in my development database and no other queries or procedure are running in same database. A query is execting unecessary very frequently although it is not that procedure.
The number of execution of that query I am able to view in V$sql.
The output of v$sql is as follows :-
SQL_TEXT SHARABLE_MEM PERSISTENT_MEM RUNTIME_MEM SORTS LOADED_VERSIONS OPEN_VERSIONS USERS_OPENING EXECUTIONS USERS_EXECUTING LOADS FIRST_LOAD_TIME INVALIDATIONS PARSE_CALLS DISK_READS BUFFER_GETS ROWS_PROCESSED COMMAND_TYPE OPTIMIZER_MODE OPTIMIZER_COST PARSING_USER_ID PARSING_SCHEMA_ID KEPT_VERSIONS ADDRESS TYPE_CHK_HEAP HASH_VALUE CHILD_NUMBER MODULE MODULE_HASH ACTION ACTION_HASH SERIALIZABLE_ABORTS OUTLINE_CATEGORY
select count(1) from "CPS"."CG016_DATA_IN" where "CSS_RESPS_SEQ" = :1 4995 520 1328 5 1 0 0 5 0 1 2006-03-23/06:10:44 0 1 2 25 5 3 CHOOSE 0 0 0 0 808BD240 00 3502453221 0 0 0 0
Could you please tell me what might be the reason due to this query is coming in v$sql although it is not there in code any where.
It seems query ( select count(1) from "CPS"."CG016_DATA_IN" where "CSS_RESPS_SEQ" = :1) is generating by oracle dynamically.
Waiting for your response....
March 23, 2006 - 10:42 am UTC
You have a foreign key.
You are deleting from the parent.
We are checking for any child records.
(make sure that foreign key is INDEXED! else a full scan for every parent row deleted)
v$sql
Anoop Gupta, March 24, 2006 - 6:43 am UTC
Tom Thanks for your prompt response....
This is really very useful for me always.....
Elapsed time
Sunil, August 21, 2007 - 6:24 am UTC
Hi Tom,
I'm bit perplexed by the elapsed time in my v$sql
UPDATE ods_router_tables SET last_data_received = :b1, last_data_received_dst = :b3 WHERE table_name = :b2 AND NVL(last_data_received,TO_DATE('01-JAN-1980','DD-MON-YYYY')) < :b1
Executions: 2786327
Disk reads: 0
Buffer gets: 6023381
Rows processed: 423713
Optimizer cost: 1
Sorts: 0
CPU Time: 898500000
Elapsed Time: 1.84467440681166E19
This table is quite small, only 44 records and if i run the statement in Sql plus, it runs in a flash. But why this enormous Elapsed time in V$SQL. Is my conversion of this time to seconds/execution correct?
Elapsed time in seconds/execution: 1.84467440681166E19/1000000/2786327=6620451 seconds!
I guess there is something seriously wrong here. I'm running on a 4 CPU server.
I see similar figures in some of the innocent looking Insert statements as well.
thanks in advance,
Sunil
August 22, 2007 - 11:29 am UTC
looks like a bad value.
it is obviously wrong - please utilize support. might be an overflow (typically seen in parallel query execution
Weird behaviour on 11g
A reader, March 14, 2013 - 4:29 pm UTC
Tom,
I have this scenario where I rewrote a query thats running on a RAC environment and it generated two different plans for two
different sets of inputs.
I am using binds.
Now, I did an alter system flush shared_pool and the entries dissapeared from gv$sqlarea.
the weird thing is, when I check after some time, they reappear with the same plan_hash_value and same (ie old) first_load_time.
How is that possible?
thanks,
March 25, 2013 - 2:34 pm UTC
well, the plans are to be expected. Sounds like adaptive cursor sharing - where a plan will be developed based on the bind inputs and multiple plans are definitely permitted. So, that isn't a surprise.
flushing the shared pool will remove what it can - but that doesn't mean everything goes. If bits of that cursor are had to stick around (perhaps that query was open somewhere) - then it will. the plans might get flushed (we can recreate those easily).
remember plsql does things like caching of cursors.
consider - single user (just me, i know no one else is running this sql) and I reset my session (force all cursors to truly close)
ops$tkyte%ORA11GR2> connect /
Connected.
ops$tkyte%ORA11GR2> alter system flush shared_pool;
System altered.
ops$tkyte%ORA11GR2> declare
2 cursor c is select * from scott.emp where 1=0;
3 begin
4 open c;
5 close c;
6 end;
7 /
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';
SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:33:11
ops$tkyte%ORA11GR2> connect /
Connected.
ops$tkyte%ORA11GR2> alter system flush shared_pool;
System altered.
ops$tkyte%ORA11GR2> exec dbms_lock.sleep(5);
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> declare
2 cursor c is select * from scott.emp where 1=0;
3 begin
4 open c;
5 close c;
6 end;
7 /
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';
SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:33:15
new first load time... however:
ops$tkyte%ORA11GR2> connect /
Connected.
ops$tkyte%ORA11GR2> alter system flush shared_pool;
System altered.
ops$tkyte%ORA11GR2> declare
2 cursor c is select * from scott.emp where 1=0;
3 begin
4 open c;
5 close c;
6 end;
7 /
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';
SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:34:17
ops$tkyte%ORA11GR2> REM connect /
ops$tkyte%ORA11GR2> alter system flush shared_pool;
System altered.
ops$tkyte%ORA11GR2> exec dbms_lock.sleep(5);
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> declare
2 cursor c is select * from scott.emp where 1=0;
3 begin
4 open c;
5 close c;
6 end;
7 /
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';
SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:34:17
comment out that reconnect - and the cursor "stays", it could not be flushed right then.