viernes, 31 de agosto de 2007

Estado de los cursores

A menudo veo que los desarrolladores y DBA's consultan la vista V$OPEN_CURSOR para identificar todos los cursores que se encuentran abiertos en la sesión. Pero esta vista muestra realmente los cursores actualmente abiertos en la sesión? La respuesta es NO.

Veamos un ejemplo:

Consultamos la vista V$OPEN_CURSOR:

SQL_9iR2> SELECT count(*)
2 FROM v$open_cursor ;

COUNT(*)
----------
169

1 row selected.

La vista nos muestra que tenemos 169 cursores abiertos. Pero en realidad lo que nos está mostrando es la cantidad de cursores actualmente abiertos en la sesión y los cursores que se encuentran actualmente cerrados (pero abiertos). Estos cursores que se encuentran cerrados pero cacheados, son los cursores que Oracle mantiene silenciosamente abiertos con la esperanza de que los volvamos a utilizar en la sesión.
Pero porque Oracle cachea los cursores? Principalmente para reducir la cantidad de parseos. Este cacheo de cursores es muy importante en aplicaciones como Oracle Forms, que suelen cerrar todos los cursores abiertos por el form principal cuando se cambia de un form a otro. Entonces, cacheando los cursores reducimos en gran medida los parseos que se realizan. Por otro lado, como reducimos la cantidad de parseos, reducimos también los loqueos (latches) que se realizan el la Library Cache y en la Shared Pool.

Suelo crear en mis bases de datos la vista MY_STATS para que los desarrolladores puedan consultar fácilmente las estadísticas de sus respectivas sesiones:

SQL_9iR2> CREATE VIEW my_stats AS
2 SELECT s.*, n.name
3 FROM v$mystat s, v$statname n
4 WHERE s.statistic# = n.statistic# ;

View created.

Veamos que suecede si consultamos el valor del parámetro 'opened cursors current' de la vista MY_STATS:

SQL_9iR2> SELECT *
2 FROM my_stats
3 WHERE name = 'opened cursors current' ;

SID STATISTIC# VALUE NAME
---------- ---------- ---------- -----------------------------------------------
43 3 4 opened cursors current

1 row selected.

Vemos que nos devuelve el valor 4. Esa es la cantidad real de cursores actualmente abiertos en nuestra sesión.

2 comentarios:

estoracle dijo...

Buenas, gracias por tu explicacion, pero, y si queremos ver los de otro usuario?
Con v$open_cursor podemos ver todos los sid ademas de los de dba, con
SELECT s.*, n.name
FROM v$mystat s, v$statname n
WHERE s.statistic# = n.statistic#
and name = 'opened cursors current'
solo el sid de la sesion (igual que con gv$mystat y gv$statname).
un saludo.

Leonardo Horikian dijo...

Hola, si queres ver los de otro usuario, en vez de utilizar la vista V$MYSTATS, podes usar la vista V$SESSTAT (ahí tenes los SID de todas las sesiones).

La consulta modificada sería:

SELECT s.*, n.name
FROM v$sesstat s, v$statname n
WHERE s.statistic# = n.statistic#
and name = 'opened cursors current'
and sid = &sid ;

Si consultas la V$OPEN_CURSOR, no vas a poder distinguir los cursores que realmente tenes abiertos.

Saludos.