sql >> Base de Datos >  >> RDS >> Oracle

V$SQL_SHARED_CURSOR TOP_LEVEL_RPI_CURSOR

Recientemente estuve trabajando con una persona en una pregunta en los foros de MOSC donde preguntaron sobre la columna TOP_LEVEL_RPI_CURSOR de la vista V$SQL_SHARED_CURSOR. Hay poca documentación sobre lo que esta columna intenta decirle al DBA.

Todo lo que dicen los documentos de Oracle es que esta columna contiene "(Y | N) Es un cursor RPI de nivel superior". Entonces, ¿qué significa eso?

Asumiré que el lector de esta publicación está familiarizado con los cursores secundarios. Eso me ahorrará una gran cantidad de información introductoria. La vista V$SQL_SHARED_CURSOR le dirá al DBA por qué un cursor secundario y su principal tienen versiones diferentes en el grupo compartido. Si la columna OPTIMIZER_MISMATCH del cursor secundario contiene una 'Y' en esta vista, entonces la sesión que ejecuta el cursor tenía configuraciones de optimizador diferentes a las de la sesión responsable de la ejecución del cursor principal.

Entonces, ¿qué significa cuando TOP_LEVEL_RPI_CURSOR se establece en Y para un niño? La documentación no es clara. MOS tiene muy poco sobre el tema. Y todos mis resultados de Google en esta columna prácticamente solo regurgitan la documentación. Para saber por qué, es útil saber que RPI significa Interfaz de programa recursiva. Esto es parte del kernel de Oracle que se ocupa de SQL recursivo. En nuestro caso, se trata del hecho de que la declaración SQL se emitió a una "profundidad" diferente.

¿Qué es SQL recursivo? Es SQL el que se emite en su nombre, lo que significa que tiene una profundidad diferente, como ilustraré. En primer lugar, Oracle realiza SQL recursivo todo el tiempo. En un nivel básico, cuando emite "select * from table_name", Oracle consulta el diccionario de datos para garantizar que el objeto existe y que tiene permisos en esa tabla. ¿Cómo hace eso Oracle? Utiliza otras sentencias SQL. La declaración que emite está en el nivel 0, el nivel base. Cuando Oracle emite una instrucción SQL para verificar si la tabla existe, estará en el siguiente nivel, el nivel 1. A veces, eso hará que se emitan otras declaraciones SQL en el siguiente nivel, el nivel 2.

La profundidad de una instrucción SQL no se limita solo a lo que Oracle está haciendo en segundo plano, en su nombre. Considere cuándo ejecuta un procedimiento almacenado. Su llamada al procedimiento almacenado está en profundidad 0. Cualquier instrucción SQL en el procedimiento almacenado está en profundidad 1. Si ese procedimiento almacenado llama a otro procedimiento, el SQL en el otro procedimiento estará en profundidad 2.

Usé esta información sobre SQL recursivo y profundidad de SQL para construir un ejemplo simple en mi base de datos Oracle 12.1.0.2. Primero, creé un procedimiento almacenado.

create or replace procedure my_sysdate 
as 
 v_dt date;
begin
 select sysdate into v_dt from dual;
end;
/

Luego inicié una sesión de SQL*Plus e inicié un seguimiento. Emití la misma instrucción SQL y luego llamé a mi procedimiento.

SQL> alter session set sql_trace=true;
Session altered.
SQL> SELECT SYSDATE FROM DUAL
 2 /
SYSDATE
---------
05-APR-16
SQL> exec my_sysdate;
PL/SQL procedure successfully completed.
SQL> exit

Cuando examiné el archivo de seguimiento sin procesar, encontré las dos llamadas a SYSDATE desde DUAL de la siguiente manera:

ANÁLISIS EN CURSOR #140670990815296 len=24 dep=0 uid=9449 oct=3 lid=9449 tim=24905125014484 hv=124468195 ad=’81477be0′ sqlid=’c749bc43qqfz3′ SELECCIONAR SYSDATE DESDE DUAL

ANÁLISIS EN CURSOR #140670907623848 len=24 dep=1 uid=9449 oct=3 lid=9449 tim=24905129780963 hv=124468195 ad=’81477be0′ sqlid=’c749bc43qqfz3′ SELECCIONAR SYSDATE DESDE DUAL

Si observa detenidamente el archivo de seguimiento, verá que el segundo en profundidad =1 fue un resultado directo del procedimiento almacenado. Tenga en cuenta que aunque mi procedimiento almacenado se definió en minúsculas, el SQL emitido en profundidad =1 estaba en mayúsculas. Como resultado, cuando emití la misma declaración de SQL directamente en mi sesión de SQL*Plus (a profundidad=0), tuve que usar la misma forma en mayúsculas de esa declaración para que tuviera el mismo valor de ID de SQL.

El archivo de seguimiento también muestra el ID de SQL. Ahora puedo consultar V$SQL_SHARED_CURSOR para ese valor de ID de SQL y mostrar que TOP_LEVEL_RPI_CURSOR está configurado para el niño.

SQL> select sql_id,top_level_rpi_cursor from v$sql_shared_cursor where sql_id='c749bc43qqfz3';
SQL_ID T
------------- -
c749bc43qqfz3 N
c749bc43qqfz3 Y

Así que ahí tenemos nuestra prueba. La única diferencia entre estos dos cursores es que uno era la profundidad desde la que se ejecutaban. No estoy seguro de por qué Oracle necesita esta distinción en el grupo compartido. Si alguien sabe, escríbame.

Normalmente, no nos importan algunas versiones adicionales, algunos cursores secundarios para una ID de SQL determinada. Si su declaración SQL tiene una gran cantidad de versiones, probablemente no se deba a los diferentes niveles de profundidad. Otras razones serían más relevantes para explicar por qué una declaración SQL tendría una gran cantidad de cursores secundarios, una gran cantidad de versiones diferentes. Pero esto responde a la pregunta de qué nos dice esa columna.