Oracle
 sql >> Base de données >  >> RDS >> Oracle

Coût de la requête :tables temporaires globales par rapport aux collections (tableaux virtuels)

Les tables temporaires globales peuvent avoir des statistiques comme n'importe quelle autre table. En fait, ils sont comme n'importe quelle autre table, ils ont des segments de données, juste dans un tablespace temporaire.

Dans 11g, les statistiques sont globales, elles causent donc parfois des problèmes avec les plans d'exécution. Dans 12c, ils sont basés sur la session afin que chaque session obtienne la bonne (si disponible).

La cardinalité du type de collection est basée sur la taille du bloc DB et pour le bloc de 8 ko par défaut est 8168. Le contenu de la collection est stocké dans PGA. Il est assez courant d'indiquer la cardinalité lors de l'utilisation de types de collection dans des requêtes complexes pour indiquer l'optimiseur. Vous pouvez également utiliser l'interface d'optimisation étendue pour implémenter votre propre méthode de calcul des coûts.

Edit - tests ajoutés :

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;

Dans ce cas, l'accès à GTT est environ deux fois plus rapide qu'à la collecte, cca 200 ms contre 400 ms sur ma machine de test. Lorsque j'ai augmenté le nombre de lignes à 10 000 000, j'ai obtenu ORA-22813 :la valeur de l'opérande dépasse les limites du système lors de la deuxième requête.