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

Leistungsüberlegungen für temporäre Daten in Oracle

Temporäre Tabellen sind dank Caching und asynchroner E/A effektiv mit In-Memory-Tabellen identisch, und die Lösung für temporäre Tabellen erfordert keinen Overhead für die Konvertierung zwischen SQL und PL/SQL.

Bestätigung der Ergebnisse

Beim Vergleich der beiden Versionen mit RunStats sieht die temporäre Tabellenversion aus viel schlimmer. All dieser Müll für die temporäre Tabellenversion in Run1 und nur ein wenig zusätzlicher Speicher für die PL/SQL-Version in Run2. Auf den ersten Blick scheint PL/SQL der klare Sieger zu sein.

Type  Name                              Run1 (temp) Run2 (PLSQL)         Diff
----- -------------------------------- ------------ ------------ ------------
...
STAT  physical read bytes                    81,920            0      -81,920
STAT  physical read total bytes              81,920            0      -81,920
LATCH cache buffers chains                  104,663          462     -104,201
STAT  session uga memory                    445,488      681,016      235,528
STAT  KTFB alloc space (block)            2,097,152            0   -2,097,152
STAT  undo change vector size             2,350,188            0   -2,350,188
STAT  redo size                           2,804,516            0   -2,804,516
STAT  temp space allocated (bytes)       12,582,912            0  -12,582,912
STAT  table scan rows gotten             15,499,845            0  -15,499,845
STAT  session pga memory                    196,608   19,857,408   19,660,800
STAT  logical read bytes from cache     299,958,272            0 -299,958,272

Aber am Ende des Tages zählt nur die Wanduhrzeit. Sowohl das Laden als auch das Abfragen laufen mit temporären Tabellen viel schneller ab.

Die PL/SQL-Version kann verbessert werden, indem BULK COLLECT ersetzt wird mit cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t . Aber es ist immer noch deutlich langsamer als die temporäre Tabellenversion.

Optimierte Lesevorgänge

Das Lesen aus der kleinen temporären Tabelle verwendet nur den Puffercache, der sich im Arbeitsspeicher befindet. Führen Sie nur den Abfrageteil viele Male aus und beobachten Sie, wie der consistent gets from cache (Speicher) erhöhen, während der physical reads cache (Festplatte) bleiben gleich.

select name, value
from v$sysstat
where name in ('db block gets from cache', 'consistent gets from cache', 
'physical reads cache');

Optimierte Schreibvorgänge

Idealerweise gäbe es keine physischen I/Os, besonders da die temporäre Tabelle ON COMMIT DELETE ROWS ist . Und es hört sich so an, als ob die nächste Version von Oracle einen solchen Mechanismus einführen könnte. Aber es spielt in diesem Fall keine große Rolle, die Festplatten-E/A scheint die Dinge nicht zu verlangsamen.

Führen Sie den Ladeschritt mehrmals aus und führen Sie dann select * from v$active_session_history order by sample_time desc; aus . Die meisten I/Os sind BACKGROUND , was bedeutet, dass nichts darauf wartet. Ich gehe davon aus, dass die interne Logik der temporären Tabelle nur eine Kopie der regulären DML-Mechanismen ist. Im Allgemeinen können neue Tabellendaten darf müssen auf die Festplatte geschrieben werden, wenn sie festgeschrieben ist. Oracle kann damit beginnen, daran zu arbeiten, beispielsweise indem es Daten aus dem Protokollpuffer auf die Festplatte verschiebt, aber es gibt keine Eile, bis es ein tatsächliches COMMIT gibt .

Wo bleibt die PL/SQL-Zeit?

Ich habe keine Ahnung. Gibt es mehrere Kontextwechsel oder eine einzelne Konvertierung zwischen den SQL- und PL/SQL-Engines? Soweit ich weiß, zeigt keine der verfügbaren Metriken die Zeit Ausgaben für den Wechsel zwischen SQL und PL/SQL.

Wir werden vielleicht nie genau wissen, warum PL/SQL-Code langsamer ist. Ich mache mir darüber keine allzu großen Sorgen. Die allgemeine Antwort ist, dass die überwiegende Mehrheit der Datenbankarbeit sowieso in SQL erledigt werden muss. Es würde sehr viel Sinn machen, wenn Oracle mehr Zeit damit verbringen würde, den Kern ihrer Datenbank, SQL, zu optimieren, als die Add-on-Sprache, PL/SQL.

Zusätzliche Hinweise

Für Leistungstests kann es hilfreich sein, den connect by zu entfernen Logik in einen separaten Schritt. Dieses SQL ist ein großartiger Trick zum Laden von Daten, aber es kann sehr langsam und ressourcenintensiv sein. Es ist realistischer, mit diesem Trick eine Beispieltabelle einmal zu laden und dann aus dieser Tabelle einzufügen.

Ich habe versucht, die neue Oracle 12c-Funktion, temporäres Rückgängigmachen, und die neue 18c-Funktion, private temporäre Tabellen, zu verwenden. Keine von beiden verbesserte die Leistung gegenüber regulären temporären Tabellen.

Ich würde nicht darauf wetten, aber ich sehe eine Möglichkeit, dass sich die Ergebnisse mit zunehmender Datenmenge vollständig ändern würden. Der Protokollpuffer und der Puffercache können nur so groß werden. Und schließlich könnte sich diese Hintergrund-E/A summieren und einige Prozesse überwältigen, was den BACKGROUND umdreht warte in einen FOREGROUND warte ab. Andererseits gibt es für die PL/SQL-Lösung nur so viel PGA-Speicher, und dann stürzt die Sache ab.

Letztendlich bestätigt dies teilweise meine Skepsis gegenüber "In-Memory-Datenbanken". Caching ist nichts Neues, Datenbanken tun es seit Jahrzehnten.