Une nouveauté sur la 11g est l'apparition de l'ACS pour Adaptive Cursor Sharing. Cette nouvelle fonctionnalité permet de pallier aux problèmes de bind rencontrer sur les requêtes SQL utilisant des paramètres.
Rappel : Il est possible d'utiliser des variables ou des litéraux dans les requêtes. Les litéraux sont des valeurs en dur dans la requête (type='manager' par exemple). Chaque requête génère alors un plan potentiellement différent pour chaque valeur du litéral. Plus le nombre requête avec des valeurs différentes est important plus la consommation mémoire dans le sharepool est importante.
De plus le calcul d'un nouveau plan (hard parse) est très couteux en CPU. Pour pallier cette problématique, l'utilisation des variables dans les requêtes permet de limiter ce problème car un seul plan est déterminé par l'optimiseur et les valeurs. Les requêtes suivantes vont reprendre le plan calculé (soft parse). Le problème c'est que le premier plan calculer n'est pas forcement le plus optimal suivant les valeurs utilisées pour chaque variable.
Un paramètre d'initialisation : CURSOR_SHARING pouvait prendre plusieurs valeurs et le comportement de l'optimiseur est différent suivant qu'il y ai ou non des histogrammes sur les colonnes :
Prenons un exemple de requête :
SELECT * FROM emp WHERE TYPE='Manager'
CURSOR_SHARING | Consommation Mémoire | Performance de la requête | Comportement de l'optimiseur |
EXACT | La plus forte (chaque requête a son propre curseur) | la meilleure (chaque requête a son propre plan, optimal pour les litéraux utilisés) |
l'optimiseur vous la requête tel quelle (qu'il y ai ou non des histogrammes) |
FORCE | La meilleure (la plus réduite possible) | potentiellement le pire, l'optimiseur forcant l'utilisation de variable et ne calculant alors qu'un seul plan. | l'optimiseur force le remplacement du ou des litéraux par des variables (qu'il y ai ou non des histogrammes) --> where type=:a |
SIMILAR sans Histo | La meilleure (la plus réduite possible) | potentiellement le pire, l'optimiseur forcant l'utilisation de variable et ne calculant alors qu'un seul plan. | Le fait qu'il n'y ai pas d'histogramme indique pour l'optimiseur que la colonne est répartie de manière équitable (not skew = pas de biais), il va donc utiliser le remplacement de la ou les variables --> where type=:a |
SIMILAR avec Histo | Pas autant que le mode EXACT mais assez proche tout de même | la meilleure (chaque requête a son propre plan, optimal pour les litéraux utilisés) | Pour l'optimiseur le fait qu'il y ai un histogramme lui indique que la colonne contient des données non uniformement distribuées (les valeurs peuvent influencer le plan). Dans ce cas, il n'opére pas de modification de la requête. --> where type='Manager' |
Avec l'ACS, le comportement de l'optimiseur est un peut plus complexe :
Prenons une requête un peu plus complexe comme example:
SELECT * FROM emp WHERE sal=:1 AND dept=:2
Voici les 4 phases possibles suivant l'arrivé des requêtes :
Phases | |
![]() |
La première requête entraîne obligatoirement un hard parse et l'optimiseur trouve un plan d'éxécution P1 et créée un cube de séléctivité CS1. |
![]() |
La deuxième requête est incluse dans le cube de séléctivité 1 (CS1) il y a donc un soft parse direct. Pas de nouveau plan cherché, l'optimiseur utilise directement le plan existant. |
![]() |
La troisième requête est en dehors de CS1, l'optimiseur déclenche donc un Hard Parse et calcule un nouveau plan d'éxécution P2 différent du premier plan P1. Un deuxième cube de sélectivité est créé CS2. |
![]() |
Une quatrième requête est lancée, elle est en dehors de CS1 et CS2, il y a donc un hard parse pour calculer un nouveau plan. Le plan calculé se trouve être le même que le premier (P1). Le cube de selectivité CS1 est alors étendu réduisant ainsi le "risque" de hard parse pour les prochaines requêtes. |