Oracle: Unterschied zwischen deterministischem und result_cache

Vom Übersetzer: Ich beschloss, meine Reise nach Habr nicht mit dem Versuch zu beginnen, einen einzigartigen Text von Grund auf neu zu schreiben, sondern mit der Übersetzung eines relativ frischen Artikels (vom 17.08.2020) der klassischen PL / SQL-Entwicklung Stephen Feuerstein , in dem er den Unterschied zwischen den beiden Hauptvarianten des Ergebniscaches der PL / SQL-Funktion ausführlich genug diskutiert. Ich hoffe, diese Übersetzung ist hilfreich für viele Entwickler, die mit Oracle-Technologien beginnen.





Einführung

Früher oder später wird jedem erfahrenen Oracle-Entwickler eine Frage gestellt wie:





Ich verstehe nicht genau, was der Unterschied zwischen deterministisch und result_cache ist. Haben sie unterschiedliche Anwendungsfälle? Ich verwende deterministisch in vielen Funktionen, die Daten aus Nachschlagetabellen abrufen. Muss ich das Schlüsselwort result_cache anstelle von deterministisch verwenden?





Ich dachte, es lohnt sich, über die Unterschiede zwischen diesen beiden Möglichkeiten zu schreiben. Zuerst lassen Sie uns sicherstellen , dass alles , was wir haben das gleiche Verständnis , wenn eine Funktion ist deterministisch .





Die Wikipedia bietet die folgende Definition eines deterministischen Algorithmus:





Ein deterministischer Algorithmus ist ein Algorithmus, der denselben Satz von Ausgaben für denselben Satz von Eingaben zurückgibt, während dieselbe Abfolge von Aktionen ausgeführt wird.





Mit anderen Worten, eine deterministische Subroutine (Prozedur oder Funktion) hat keine Nebenwirkungen. Wenn Sie einen bestimmten Wertesatz als Eingabeparameter übergeben, erhalten Sie am Ausgang immer das gleiche Ergebnis, unabhängig davon, wann, wo oder wie oft Sie diese Unterroutine aufrufen.





Eine vernünftige Frage ist, was ist ein Nebeneffekt einer PL / SQL-Funktion? Zumindest (die Liste ist nicht vollständig):





  • Beliebiger (dh beliebiger) DML-Operator





  • Verwenden einer außerhalb dieser Funktion deklarierten Variablen (dh global, außerhalb des Gültigkeitsbereichs, auch bekannt als "global")





  • Rufen Sie eine nicht deterministische Unterroutine auf





, deterministic result_cache , . . ( result_cache), , , .





FUNCTION betwnstr (
   string_in   IN   VARCHAR2
 , start_in    IN   INTEGER
 , end_in      IN   INTEGER
)
   RETURN VARCHAR2 DETERMINISTIC 
IS
BEGIN
   RETURN (SUBSTR (string_in, start_in, end_in - start_in + 1));
END;
      
      



- substr



, , . , , .





, Oracle Database , DETERMINISTIC



( ).





?





  • ,





  • ( )





, :





CREATE OR REPLACE FUNCTION pass_number (i NUMBER)
   RETURN NUMBER
   DETERMINISTIC
IS
BEGIN
   DBMS_OUTPUT.put_line ('pass_number executed');
   RETURN 0;
END;
/

DECLARE
   n   NUMBER := 0;
BEGIN
   FOR rec IN (SELECT pass_number (1)
                 FROM all_objects
                WHERE ROWNUM < 6)
   LOOP
      n := n + 1;
   END LOOP;

   DBMS_OUTPUT.put_line (n + 1);
END;
/

pass_number executed
6
      
      



, , 5 , . Oracle Database , ( PL/SQL SQL-, ).





.





, result_cache

betwnstr



, result_cache:





FUNCTION betwnstr (
   string_in   IN   VARCHAR2
 , start_in    IN   INTEGER
 , end_in      IN   INTEGER
)
   RETURN VARCHAR2 
   RESULT_CACHE
IS
BEGIN
   RETURN (SUBSTR (string_in, start_in, end_in - start_in + 1));
END;
      
      



- RESULT_CACHE



. , DETERMINISTIC



, . , result_cache.





result_cache? :





  • Oracle Database, SGA (Shared Global Area)





  • , ,





  • ( "" )





  • ( Oracle - , references) , commit





, . RESULT_CACHE



- "" DETERMINISTIC



( , ) . RESULT_CACHE



, . RESULT_CACHE



Oracle Live SQL.





, , RESULT_CACHE



:





CREATE OR REPLACE FUNCTION pass_number (i NUMBER)
   RETURN NUMBER
   RESULT_CACHE
IS
BEGIN
   DBMS_OUTPUT.put_line ('pass_number executed for ' || i);
   RETURN 0;
END;
/

DECLARE
   n   NUMBER := 0;
BEGIN
   FOR rec IN (SELECT pass_number (100)
                 FROM all_objects
                WHERE ROWNUM &lt; 6)
   LOOP
      n := n + 1;
   END LOOP;

   DBMS_OUTPUT.put_line ('All done ' || TO_CHAR (n + 1));
END;
/

pass_number executed for 100
All done 6


BEGIN
   DBMS_OUTPUT.PUT_LINE ('Returned ' || pass_number (100));
   DBMS_OUTPUT.PUT_LINE ('Returned ' || pass_number (200));
   DBMS_OUTPUT.PUT_LINE ('Returned ' || pass_number (300));
   DBMS_OUTPUT.PUT_LINE ('Returned ' || pass_number (100));
   DBMS_OUTPUT.PUT_LINE ('Returned ' || pass_number (200));
   DBMS_OUTPUT.PUT_LINE ('Returned ' || pass_number (300));
END;
/

Returned 0
pass_number executed for 200
Returned 0
pass_number executed for 300
Returned 0
Returned 0
Returned 0
Returned 0
      
      



100 ( ), , , .





200 300 - , .





! ( ) PL/SQL , :





All done 6
Returned 0
Returned 0
Returned 0
Returned 0
Returned 0
Returned 0
      
      



, RESULT_CACHE



, , . , - - .





: , result_cache, , .





deterministic result_cache?

DETERMINISTIC



RESULT_CACHE



.





?

, , DETERMINISTIC



, ( ) ( SQL-, ). , , .





, , , RESULT_CACHE



, (instance) , ( , ) . , .





?

: DETERMINISTIC



, .





PL/SQL SQL, , (, ).





, . , , .





DETERMINISTIC



, . Oracle , , .





, result_cache?

. RESULT_CACHE



. DBA, , . , SGA , (latch contention).





, result_cache. :





  • ?





  • , ? ,





  • , , , ? , ,





  • - , NLS? , , , , TO_CHAR



      .





: RESULT_CACHE



, , , .








All Articles