Hi,
I'm trying to understand statement caching and its usage via OCI as described in the OCI documentation (Oracle 9.2.0,
http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96584/oci09adv.htm#464310).
1. The documentation states "Statement caching refers to the feature, first introduced in release 9.2, that provides and manages a cache of statements for each session. In the server, it means that cursors are ready to be used without the need to parse the statement again."
As far as I know, SQL statements are always cached in Oracle, although the corresponding cursors might be closed again. If I understand the OCI documentation correctly, the term "statement caching" really means cursor caching. Is that correct? Or is there additional caching of statements within the oci, i.e. on the client side?
2. The OCI documentation states that the following calls implement statement caching: OCIStmtPrepare2() and OCIStmtRelease()
From this I gather that there will be no statement caching when using OCIStmtPrepare() and OCIHandleFree(). So I changed our application code to use OCIStmtPrepare2/OCIStmtRelease instead of the former two.
Then I tried to measure whether using OCIStmtPrepare2/OCIStmtRelease had any effect. For this I run a testcase of my application and watched the cursor cache using the following statement which I found on the web and which supposedly tells how many cursors are currently cached in a session:
SELECT a.VALUE,
s.username,
s.sid,
s.serial#
FROM v$sesstat a,
v$statname b,
v$session s
WHERE a.statistic# = b.statistic#
AND s.sid = a.sid
AND b.name = 'session cursor cache count'
AND s.sid = <the sid of my application's session>;
And really, the count steadily increased during the test run until it reached 100 which is the configured maximum of cached cursors in our database.
But when I changed the application code back to using OCIStmtPrepare/OCIHandleFree there was no difference when running the test again! I would have expected the count to stay at zero?! Probably I'm misunderstanding something or the query does not do what I'm expecting?
3. I further tried to measure the cache hit ratio during the same test run by using the following statement (again found on the web, in the same blog entry as the previous one):
select cach.value cache_hits, prs.value all_parses,
prs.value-cach.value sess_cur_cache_not_used
from v$sesstat cach, v$sesstat prs, v$statname nm1, v$statname nm2
where cach.statistic# = nm1.statistic#
and nm1.name = 'session cursor cache hits'
and prs.statistic#=nm2.statistic#
and nm2.name= 'parse count (total)'
and cach.sid= <the sid of my application's session> and prs.sid= cach.sid;
When running with OCIStmtPrepare2/OCIStmtRelease I got 70 cache hits (out of about 390). When running with OCIStmtPrepare/OCIHandleFree I got 51 cache hits. This I do not understand either. Can anyone explain this to me?
4. When calling OCIStmtRelease I'm setting the mode parameter to 0x0010. The OCI documentation mentions the mode OCI_STMTCACHE_DELETE which means to delete the stmt from the cache. The oci.h does not contain this parameter at all, but just the following which I assumed to be the same, so I used it:
/* OCIStmtRelease Modes */
#define OCI_STRLS_CACHE_DELETE 0x0010 /* Delete from Cache */
What I do not really understand is the meaning of "Delete from Cache". As I'm trying to use caching, I'd just like to release the statement/cursor to the cache for reuse, not delete it from the cache. Curiously when using OCI_DEFAULT instead, the measurement statements above detect no caching, i.e. the cache count stays at zero and there are no cache hits. This seems to be contrary to the documentation. Can anyone shed light on this?
I'm grateful for any help!
Thanks a lot.