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

Considérations sur les performances des données temporaires dans Oracle

Les tables temporaires sont effectivement les mêmes que les tables en mémoire grâce à la mise en cache et aux E/S asynchrones, et la solution de table temporaire ne nécessite aucune surcharge pour la conversion entre SQL et PL/SQL.

Confirmation des résultats

En comparant les deux versions avec RunStats, la version de la table temporaire regarde bien pire. Tout ce bazar pour la version de la table temporaire dans Run1, et seulement un peu de mémoire supplémentaire pour la version PL/SQL dans Run2. Au début, il semble que PL/SQL devrait être le grand gagnant.

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

Mais en fin de compte, seule l'heure de l'horloge murale compte. Les étapes de chargement et d'interrogation s'exécutent beaucoup plus rapidement avec les tables temporaires.

La version PL/SQL peut être améliorée en remplaçant le BULK COLLECT avec cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t . Mais c'est toujours beaucoup plus lent que la version de la table temporaire.

Lectures optimisées

La lecture de la petite table temporaire n'utilise que le tampon cache, qui est en mémoire. Exécutez uniquement la partie requête plusieurs fois et observez comment le consistent gets from cache (mémoire) augmente pendant que le physical reads cache (disque) reste le même.

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

Écritures optimisées

Idéalement, il n'y aurait pas d'E/S physiques, d'autant plus que la table temporaire est ON COMMIT DELETE ROWS . Et il semble que la prochaine version d'Oracle puisse introduire un tel mécanisme. Mais peu importe dans ce cas, les E/S disque ne semblent pas ralentir les choses.

Exécutez l'étape de chargement plusieurs fois, puis exécutez select * from v$active_session_history order by sample_time desc; . La plupart des E/S sont BACKGROUND , ce qui signifie que rien ne l'attend. Je suppose que la logique interne de la table temporaire n'est qu'une copie des mécanismes DML habituels. En général, les nouvelles données de table peuvent doivent être écrites sur le disque, si elles sont validées. Oracle peut commencer à travailler dessus, par exemple en déplaçant les données du tampon de journal vers le disque, mais il n'y a pas d'urgence tant qu'il n'y a pas de véritable COMMIT .

Où va le temps PL/SQL ?

Je n'ai aucune idée. Existe-t-il plusieurs changements de contexte ou une seule conversion entre les moteurs SQL et PL/SQL ? Autant que je sache, aucune des mesures disponibles n'indique le temps dépensé pour basculer entre SQL et PL/SQL.

Nous ne saurons peut-être jamais exactement pourquoi le code PL/SQL est plus lent. Je ne m'en soucie pas trop. La réponse générale est que la grande majorité du travail de base de données doit de toute façon être effectuée en SQL. Cela aurait beaucoup de sens si Oracle passait plus de temps à optimiser le cœur de sa base de données, SQL, que le langage complémentaire, PL/SQL.

Remarques supplémentaires

Pour les tests de performances, il peut être utile de supprimer le connect by logique dans une étape distincte. Ce SQL est une excellente astuce pour charger des données, mais il peut être très lent et gourmand en ressources. Il est plus réaliste de charger un exemple de table une fois avec cette astuce, puis de l'insérer à partir de cette table.

J'ai essayé d'utiliser la nouvelle fonctionnalité Oracle 12c, l'annulation temporaire, et la nouvelle fonctionnalité 18c, les tables temporaires privées. Aucune des deux n'a amélioré les performances par rapport aux tables temporaires classiques.

Je ne parierais pas là-dessus, mais je peux voir comment les résultats changeraient complètement à mesure que les données augmenteraient. Le tampon de journal et le cache de tampon ne peuvent devenir volumineux. Et éventuellement, ces E/S en arrière-plan pourraient s'additionner et submerger certains processus, transformant le BACKGROUND attendre dans un FOREGROUND Attendez. D'un autre côté, il n'y a pas assez de mémoire PGA pour la solution PL/SQL, et puis les choses plantent.

Enfin, cela confirme en partie mon scepticisme à l'égard des "bases de données en mémoire". La mise en cache n'a rien de nouveau, les bases de données le font depuis des décennies.