![]() |
|||||||||||||||||||||||||||||||||||||||||||||
|
White Paper Les curseurs Toute instruction SQL est traitée par ORACLE en tant que curseur. Un curseur est un objet qui permet à ORACLE de résoudre quelques problèmes d’interprétation, d’exécution, de partage et de performance. Le curseur consiste en un ensemble de zones mémoire dont la SGA, plus précisément le shared pool. Quand une session doit exécuter un curseur qui est déjà partagé dans le shared pool, elle doit acquérir un lien (pin) vers le handle de ce curseur. L’établissement de ce lien recharge implicitement ce curseur dans le cas de son vieillissement dans le cache, traduit par la colonne LOADS de la vue v$sqlarea. Ce vieillissement se produit notamment quand d’autres curseurs nécessitent de l’espace libre dans le cache et celui-ci a une taille inappropriée pour l’applicatif, ou lors de la présence du bug 1318267. Le phénomène de chargement est gourmand en ressources (c’est pour éviter la consommation de ces ressources employés que le cache est utilisé). Idéalement, pour une instruction SQL, un seul chargement (initial est nécessaire) même dans le cas des millions d’exécutions. Le traitement SQL Comment interpréter les statistiques concernant le shared pool ? Les trois phases de traitement SQL Nous allons étudier en détail la façon dont le process SERVER exécute un ordre SQL transmis par le process utilisateur. Le process SERVER divise l'exécution d'un ordre SQL en trois phases : Analyse ou Parsing, Execute, Fetch. Parsing et optimisation Durant cette phase, ORACLE transforme la chaîne de caractères que vous croyez être ‘un ordre SQL’ en une requête intelligible par son noyau. Quelques étapes sont franchies lors du parsing :
Les droits de l'utilisateur sur les objets référencés. Les différents chemins d'accès (indirectement).
A l'aide des informations ainsi collectées, ORACLE élabore un plan d'exécution. Ce plan d'exécution est ensuite stocké dans la SHARED POOL. Il sera partagé par tous les utilisateurs qui effectueront le MÊME ordre SQL. Le mécanisme de partage tire profit d’un algorithme de hachage qui est appliqué à l’intégralité du texte de l'ordre SQL :
En conclusion, pour partager un curseur, les ordres qui interrogent les mêmes données doivent être IDENTIQUES ! C’est pour ceci qu’idéalement les ordres souvent passés devraient passer par des procédures stockées : une procédure stockée présentera toujours le même texte au noyau, donc elle aura toujours le même résultat à la fin de la fonction de hachage. D’un autre point de vue, les procédures stockées offrent l’avantage d’être enregistrées avec le plan d’exécution, ceci réduit énormément l’étape de parsing. Globalement, le parsing est une étape gourmande en ressources et actions. En conséquence, une des actions importantes de l’optimisation de la base de données est l’optimisation des ordres SQL. Un des buts souhaités est de minimiser le parse et load des requêtes. Pendant cette phase, un lock de type KGL est posé sur les objets participants à la requête : aucune structure référencée ne peut être modifiée pendant l’opération. Hit ratio du parse Des informations concernant les diverses étapes de l’analyse sont disponibles dans quelques vues : V$LIBRARYCACHE, V$SQLAREA, V$SQL. Comme spécifié dans les paragraphes précédents, le rapport hard parses/soft parses devrait avoisiner 0. La requête suivante calcule le parse hit ratio, indicateur convenable des performances du library cache, reflet de la ‘bonne écriture des ordres SQL’ : Select 100*gethits/gets from V$LIBRARYCACHE where namespace = ‘SQL AREA’;Le résultat de cette requête devrait avoisiner 100 pour-cent (résultat impossible, au moins un hard parse est à faire pour chaque curseur). Quelques paramètres de la vue V$SQLAREA sont essentiels pour déterminer les divers problèmes d’analyse : LOADS
Nombre d’interprétations de l’ordre SQL. Un minimum de loads (valeur à un) est souhaitable.
VERSION_COUNT
Un même ordre SQL (en-tête du curseur) peut avoir plusieurs enfants (corps du curseur), en fonction de la résolution différente des synonymes, variables bind, etc.
Execute Durant la phase d'exécution de l'ordre SQL, le process SERVER :
Fetch Pendant la phase de 'Fetch', les enregistrements sont transférés depuis les buffers de données vers le process utilisateur. Comment ? Avant la 8i, le curseur (explicite ou implicite) ramène les données ligne par ligne. Depuis la 8i, le curseur peut ramener des paquets de lignes lors du fetch. LOADS INVALIDATIONS EXECUTIONS SQL_TEXT ----- ------------- ---------- -------------------------------------------------- 93453 13 22228 insert into (coupé par TAFORA)Après ----- ------------- ---------- -------------------------------------------------- LOADS INVALIDATIONS EXECUTIONS SQL_TEXT 1 0 22550 insert into (coupé par TAFORA)A voir directement sure le site TAFORA (www.tafora.fr):
Deux notions Oracle permettent de mieux ranger les instructions SQL dans le shared pool :
SQL> col name FOR a30
SQL> col TYPE FOR a15
SQL> select name, type, SHARABLE_MEM
2 from v$db_object_cache
3 where type in ('PACKAGE BODY', 'PROCEDURE', 'FUNCTION')
4 AND SHARABLE_MEM > 20000 /* ce qui dépasse 2k */
5 order by SHARABLE_MEM desc;
NAME TYPE SHARABLE_MEM
------------------------------ --------------- ------------
DRIDDL PACKAGE BODY 73829
STATSPACK PACKAGE BODY 50010
CTX_DDL PACKAGE BODY 47514
DRIUTL PACKAGE BODY 45293
DRIPARSE PACKAGE BODY 42459
. . . etc
|
||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||