Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Statisches vs. dynamisches SQL

Ihr Beispielcode ist so einfach, dass es kaum Unterschiede geben wird, aber in diesem Fall würde die statische Version höchstwahrscheinlich besser ausgeführt werden.

Der Hauptgrund für die Verwendung von dynamischem SQL für die Leistung ist, wenn die SQL-Anweisung erheblich variieren kann – d. h. Sie können der WHERE-Klausel zur Laufzeit möglicherweise zusätzlichen Code hinzufügen, basierend auf dem Zustand des Systems (Einschränkung durch eine Unterabfrage auf Adresse, falls Adresse eingegeben usw.).

Ein weiterer Grund ist, dass die Verwendung von Bind-Variablen als Parameter manchmal kontraproduktiv sein kann.

Ein Beispiel ist, wenn Sie so etwas wie ein Statusfeld haben, in dem die Daten nicht gleichmäßig verteilt (aber indiziert) sind.

Betrachten Sie die folgenden 3 Aussagen, wenn 95 % der Daten „verarbeitet“ werden

   SELECT col FROM table 
   WHERE status = 'U'-- unprocessed
   AND company = :company

   SELECT col FROM table 
   WHERE status = 'P' -- processed
   AND company = :company

   SELECT col FROM table
   WHERE status = :status
   AND company = :company

In der endgültigen Version wird Oracle einen generischen Explain-Plan wählen. In der ersten Version mag es entscheiden, dass es am besten ist, mit dem Statusindex zu beginnen (in dem Wissen, dass 'unverarbeitete Einträge nur einen sehr kleinen Teil der Gesamtheit ausmachen).

Sie könnten dies durch verschiedene statische Anweisungen implementieren, aber wenn Sie komplexere Anweisungen haben, die sich nur um ein paar Zeichen ändern, ist dynamisches SQL möglicherweise eine bessere Option.

Nachteile

Jede Wiederholung derselben dynamischen SQL-Anweisung führt zu einer Soft-Parse, was im Vergleich zu einer statischen Anweisung einen geringen Overhead darstellt, aber immer noch ein Overhead ist.

Jede NEUE SQL-Anweisung (dynamisch oder statisch) führt auch zu einer Sperre des SGA (gemeinsam genutzter Speicher) und kann dazu führen, dass „alte“ Anweisungen hinausgeschoben werden.

Ein schlechtes, aber weit verbreitetes Systemdesign ist, dass jemand dynamisches SQL verwendet, um einfache Auswahlen zu generieren, die nur nach Schlüssel variieren - z. B.

SELECT col FROM table WHERE id = 5
SELECT col FROM table WHERE id = 20
SELECT col FROM table WHERE id = 7

Die einzelnen Anweisungen werden schnell sein, aber die Gesamtsystemleistung wird sich verschlechtern, da die gemeinsam genutzten Ressourcen zerstört werden.

Außerdem ist es viel schwieriger, Fehler zur Kompilierzeit mit dynamischem SQL abzufangen. Wenn Sie PL/SQL verwenden, wirft dies eine gute Überprüfung der Kompilierungszeit weg. Selbst wenn Sie so etwas wie JDBC verwenden (wo Sie Ihren gesamten Datenbankcode in Zeichenfolgen verschieben - gute Idee!), können Sie Pre-Parser dazu bringen, den JDBC-Inhalt zu validieren. Dynamisches SQL =nur Laufzeittests.

Gemeinkosten

Der Overhead der sofortigen Ausführung ist gering – er liegt in Tausendstelsekunden – er kann sich jedoch summieren, wenn sich dies innerhalb einer Schleife / bei einer Methode befindet, die einmal pro Objekt aufgerufen wird / usw. Ich habe einmal eine 10-fache Geschwindigkeitsverbesserung erzielt, indem ich dynamic ersetzt habe SQL mit generiertem statischem SQL. Dies verkomplizierte jedoch den Code und wurde nur gemacht, weil wir die Geschwindigkeit benötigten.