Oracle
 sql >> Database >  >> RDS >> Oracle

Costo della query:tabelle temporanee globali e raccolte (array virtuali)

Le tabelle temporanee globali possono avere statistiche come qualsiasi altra tabella. In effetti sono come qualsiasi altra tabella, hanno segmenti di dati, solo in tablespace temporanee.

In 11g le statistiche sono globali, quindi a volte causano problemi con i piani di esecuzione. In 12c sono basati sulla sessione, quindi ogni sessione riceve quelle appropriate (se disponibili).

La cardinalità del tipo di raccolta si basa sulla dimensione del blocco DB e per il blocco predefinito da 8 kB è 8168. Il contenuto della raccolta è archiviato in PGA. È abbastanza comune suggerire la cardinalità quando si utilizzano tipi di raccolta in query complesse per suggerire l'ottimizzatore. Puoi anche utilizzare l'interfaccia di ottimizzazione estesa per implementare il proprio metodo di calcolo dei costi.

Modifica - test aggiunti:

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 questo caso l'accesso a GTT è circa due volte più veloce rispetto alla raccolta, circa 200 ms contro 400 ms sulla mia macchina di prova. Quando ho aumentato il numero di righe a 10 000 000, ho ottenuto ORA-22813:il valore dell'operando supera i limiti di sistema nella seconda query.