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

Abfragekosten:Globale temporäre Tabellen vs. Sammlungen (virtuelle Arrays)

Globale temporäre Tabellen können wie jede andere Tabelle Statistiken enthalten. Tatsächlich sind sie wie jede andere Tabelle, sie haben Datensegmente, nur in einem temporären Tabellenbereich.

In 11g sind die Statistiken global, sodass sie manchmal Probleme mit Ausführungsplänen verursachen. In 12c sind sie sitzungsbasiert, sodass jede Sitzung die richtigen erhält (falls verfügbar).

Die Kardinalität des Sammlungstyps basiert auf der DB-Blockgröße und ist für den standardmäßigen 8-KB-Block 8168. Der Inhalt der Sammlung wird in PGA gespeichert. Es ist durchaus üblich, die Kardinalität anzugeben, wenn Sammlungstypen in komplexen Abfragen verwendet werden, um den Optimierer anzugeben. Sie können auch die erweiterte Optimiererschnittstelle verwenden, um eine eigene Methode zur Kostenberechnung zu implementieren.

Bearbeiten - Tests hinzugefügt:

CREATE TYPE STRINGTABLE IS TABLE OF VARCHAR2(255);
CREATE GLOBAL TEMPORARY TABLE TMP (VALUE VARCHAR2(255));

INSERT INTO TMP SELECT 'Value' || LEVEL FROM DUAL CONNECT BY LEVEL <= 1000000;

DECLARE
    x STRINGTABLE;
    cnt NUMBER;
BEGIN
    SELECT VALUE BULK COLLECT INTO x FROM TMP;

    DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSTIMESTAMP, 'MI:SS.FF3'));

    SELECT SUM(LENGTH(VALUE)) INTO cnt FROM TMP;

    DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSTIMESTAMP, 'MI:SS.FF3'));

    SELECT SUM(LENGTH(COLUMN_VALUE)) INTO cnt FROM TABLE(x);

    DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSTIMESTAMP, 'MI:SS.FF3'));
END;

In diesem Fall ist der Zugriff auf GTT etwa doppelt so schnell wie auf die Sammlung, ca. 200 ms vs. 400 ms auf meinem Testcomputer. Als ich die Anzahl der Zeilen auf 10.000.000 erhöhte, erhielt ich ORA-22813:Operandenwert überschreitet Systemgrenzen bei der zweiten Abfrage.