Cet article est la traduction d’un article de Jonathan Lewis publié sur son blog. L’article original en anglais se trouve ici
Sur Oracle, certains concepts sont si fondamentaux qu’on doit toujours les avoir en tête à chaque fois qu’on veut étudier un problème de performance. Et voici l’un d’eux:
Les histogrammes et les bind variables existent pour des raison diamétralement opposées: sans y prêter garde, ils ne fonctionneront pas bien ensemble.
Vous utilisez des bind variables parce que vous voulez que tout le monde partage le même plan d’exécution pour une requête SQL qui va être utilisé fréquemment. Tout le monde va faire la même charge de travail avec (charge normalement faible). Son plan d’exécution sera optimal pour tout le monde. Et vous ne voulez pas ré-optimiser cette requête à chaque fois, car cette réoptimisation utiliserait à elle seule plus de ressources qu’il n’en faut ensuite pour l’exécuter.
En général on utilise beaucoup les bind variables lorsqu’on est en transactionnel (OLTP) – sauf quelques cas particuliers où on préférera des valeurs littérales.
Et vous créez des histogrammes pour des requêtes qui, mêmes si elles sont similaires, vont faire un travail très différent les unes des autres. Elles ont besoin de plans d’exécution différents. Et de toute façon le travail d’optimisation est négligeable par rapport au travail d’exécution de la requête. Alors que si on utilise un plan d’exécution qui n’est pas optimal, on peut se retrouver à gaspiller beaucoup de ressources.
En général, on a besoin des histogrammes en datawarehouse, en BI, où les requêtes peuvent être très grosses et coûteuses.
C’est là qu’est la contradiction: on a une technologie qui est censée nous donner un seul plan d’exécution partagé par tout le monde, et une autre qui elle est censée trouver pour chacun le plan qui lui convient le mieux.
Gardez celà en mémoire, et vous vous rappellerez qu’il faut être très prudent lorsqu’on met des histogrammes sur une base transactionnelle (OLTP) et qu’il ne faut pas non plus transformer absolument toutes les valeurs littérales en bind variables.
A noter les commentaires de Doug Burns et Hemant K Chitale sur le fait qu’en 10g Oracle collecte par défaut des histogrammes avec la méthode ‘FOR ALL COLUMNS SIZE AUTO’ de dbms_stats.