Oracle
 sql >> Baza danych >  >> RDS >> Oracle

V$SQL_SHARED_CURSOR TOP_LEVEL_RPI_CURSOR

Niedawno pracowałem z osobą nad pytaniem na forach MOSC, w którym pytano o kolumnę TOP_LEVEL_RPI_CURSOR w widoku V$SQL_SHARED_CURSOR. Niewiele jest dokumentacji na temat tego, co ta kolumna próbuje przekazać DBA.

Wszystkie dokumenty Oracle mówią, że ta kolumna zawiera „(Y|N) Jest kursorem RPI najwyższego poziomu”. Więc co to oznacza?

Zakładam, że czytelnik tego posta zna kursory dziecięce. Dzięki temu zaoszczędzę wiele wstępnych informacji. Widok V$SQL_SHARED_CURSOR poinformuje administratora DBA, dlaczego kursor podrzędny i jego rodzic mają różne wersje w puli współużytkowanej. Jeśli kolumna OPTIMIZER_MISMATCH kursora podrzędnego zawiera w tym widoku „Y”, to sesja wykonująca kursor miała inne ustawienia optymalizatora niż sesja, która była odpowiedzialna za wykonanie kursora nadrzędnego.

Więc co to znaczy, gdy TOP_LEVEL_RPI_CURSOR jest ustawiony na Y dla dziecka? Dokumentacja nie jest jasna. MOS ma bardzo niewiele na ten temat. I wszystkie moje trafienia w Google w tej kolumnie po prostu zwracają dokumentację. Aby wiedzieć dlaczego, warto wiedzieć, że RPI to skrót od Recursive Program Interface. Jest to część jądra Oracle, która zajmuje się rekurencyjnym SQL. W naszym przypadku dotyczy to faktu, że instrukcja SQL została wydana na innej „głębokości”.

Co to jest rekurencyjny SQL? To SQL jest wydawany w Twoim imieniu, co oznacza, że ​​na innej głębokości, jak to zilustruję. Po pierwsze, Oracle cały czas wykonuje rekurencyjne SQL. Na podstawowym poziomie, gdy wydajesz polecenie „wybierz * z nazwa_tabeli”, Oracle wysyła zapytanie do słownika danych, aby upewnić się, że obiekt istnieje i że masz uprawnienia do tej tabeli. Jak Oracle to robi? Używa innych instrukcji SQL. Oświadczenie, które wydajesz, jest na poziomie 0, poziomie podstawowym. Kiedy Oracle wyda instrukcję SQL, aby sprawdzić, czy tabela istnieje, będzie to następny poziom, poziom 1. Czasami spowoduje to wydanie innych instrukcji SQL na następnym poziomie, poziomie 2.

Głębokość instrukcji SQL nie ogranicza się tylko do tego, co Oracle robi w tle w Twoim imieniu. Zastanów się, kiedy wykonujesz procedurę składowaną. Twoje wywołanie procedury składowanej ma głębokość 0. Każda instrukcja SQL w procedurze składowanej ma głębokość 1. Jeśli ta procedura składowana wywołuje inną procedurę, kod SQL w tej procedurze będzie miał głębokość 2.

Użyłem tych informacji na temat rekursywnego SQL i głębokości SQL do skonstruowania prostego przykładu w mojej bazie danych Oracle 12.1.0.2. Najpierw utworzyłem procedurę składowaną.

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

Następnie odpaliłem sesję SQL*Plus i rozpocząłem śledzenie. Wydałem tę samą instrukcję SQL, a następnie wywołałem moją procedurę.

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

Kiedy sprawdziłem nieprzetworzony plik śledzenia, znalazłem dwa wywołania SYSDATE z DUAL w następujący sposób:

Parsowanie w kursorze #140670990815296 len=24 dep=0 uid=9449 oct=3 lid=9449 tim=24905125014484 hv=124468195 ad=’81477be0′ sqlid=’c749bc43qqfz3′ WYBIERZ SYSDATE Z DUAL

Parsowanie w kursorze #140670907623848 len=24 dep=1 uid=9449 oct=3 lid=9449 tim=24905129780963 hv=124468195 ad=’81477be0′ sqlid=’c749bc43qqfz3′ WYBIERZ SYSDATE Z DUAL

Jeśli przyjrzysz się uważnie plikowi śledzenia, zobaczysz, że drugi o głębokości=1 był bezpośrednim wynikiem procedury składowanej. Zwróć uwagę, że chociaż moja procedura składowana została zdefiniowana małymi literami, kod SQL wydany na głębokość=1 był zapisywany dużymi literami. W rezultacie, kiedy wydałem tę samą instrukcję SQL bezpośrednio w mojej sesji SQL*Plus (przy głębokości=0), musiałem użyć tej samej formy pisanej dużymi literami, aby miała tę samą wartość identyfikatora SQL.

Plik śledzenia zawiera również identyfikator SQL. Mogę teraz zapytać V$SQL_SHARED_CURSOR o tę wartość identyfikatora SQL i pokazać, że dla dziecka ustawiono TOP_LEVEL_RPI_CURSOR.

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

Mamy więc nasz dowód. Jedyna różnica między tymi dwoma kursorami polega na tym, że jednym z nich była głębokość, z której zostały wykonane. Nie jestem pewien, dlaczego Oracle potrzebuje tego wyróżnienia w puli współdzielonej. Jeśli ktoś wie, napisz do mnie.

Normalnie nie obchodzi nas kilka dodatkowych wersji, kilka kursorów potomnych dla danego identyfikatora SQL. Jeśli instrukcja SQL ma dużą liczbę wersji, prawdopodobnie nie wynika to z różnych poziomów głębokości. Inne powody byłyby bardziej istotne dla tego, dlaczego instrukcja SQL miałaby dużą liczbę kursorów podrzędnych, dużą liczbę różnych wersji. Ale to odpowiada na pytanie, co mówi nam ta kolumna.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zrekonstruuj rezerwową bazę danych w stanie gotowości

  2. Czy musimy określić not null dla klucza podstawowego? Oracle/SQL

  3. ORA-01036:nieprawidłowa nazwa/numer zmiennej podczas uruchamiania zapytania przez C#

  4. Powiadomienie o zmianie bazy danych Oracle

  5. Sprawdź ograniczenie Wywoływanie funkcji Programista Oracle SQL