mercredi 5 mars 2014

Optimisation de requête SQL (Oracle)

Alors comment optimiser ses requêtes pour optimiser les temps de traitement (Oracle) ?

Tout d'abord il faut savoir que le SGBD utilise un plan d'exécution pour effectuer les instructions demandées.


- Comment fait-il ? Il calcul un plan d'exécution optimisé suivant des algorithmes en fonction des informations qu'il possède, notamment de ses statistiques.


L'exécution de la requête se fait de la plus profonde à l'extérieur (la sous sous sous requête avant la requête affichant le résultat).


- Que va t'il regarder ? Tout d'abord il va regarder les différents index existants sur les tables/objets utilisés dans la requête notamment les clés primaires (index unique) ; à partir des méta-données & statistiques (après un analyse "compute statistic" par exemple). Il va alors déterminer son plan d'exécution en fonction de la volumétrie (index ou full scan) etc.


N'hésitez pas à vous faire conseiller de votre DBA (Administrateur de la base de données), qui vous aidera à savoir s'il convient de partitionner, de vous aider à choisir vos tablesspaces suivant les données physiques et volumétrie de vos tables.


Coût de la requête : le "cost"

Le Cost est un indicateur intéressant, il s'affiche lorsque l'on demande au SGBD de nous montrer son plan d'exécution.

Ce qui est le plus coûteux : La jointure


Optimisation :

  • Critères sélectif à la fin de la requête (exécutés en premier) 
    • Il convient donc de mettre en fin de requête tous les critères de sélection afin de réduire le nombre de ligne à joindre (et non l'inverse).
    • select champ1, champ2 from table1 t1, table2 t2 where t1.pk = t2.pk and t1.champ1 in ('toto','titi');
  • Il convient également de projeter uniquement les colonnes nécessaires (ramener 10 champs dont 8 ne seront pas utilisés est un volume de données inutile).
  • Table la moins volumineuse (référence) à gauche
  • Eviter les select... in(select...) utiliser select... exists(select...)
  • Utilisez des fonctions analytiques plutôt que des sous select (peut changer exponentiellement le temps d'exécution)
  • Lancer l'analyse de la table régulièrement (en full ou % suivant la volumétrie). Cela peut changer le plan d’exécution en fonction des données récupérées
  • Créer des index sur les critères de jointure (create [unique] index...)
  • Utiliser des identifiants techniques optimise la sélection des relations complexes (table dont la clé primaire et composite et de types hétérogènes (caractère,numérique...))
  • Partitionner la table dans la mesure du possible/besoin (la partition est vue comme une table à part et permet donc de réduire fortement la volumétrie) : select... from table1 partition()
  • Utilisation de hints : forcer le plan d’exécution (pour les experts : souvent l'analyse / rebuild ou création d'index / refonte de la requête suffit au SGBD de choisir le bon algorithme).
Produit Cartésien : multiplication des lignes de données car aucun lien n'est trouvé entre 2 tables

Quelques références de site :