Bonjour à tous.
Je suis en train d'optimiser les performances(du moins j'essaye) d'une application qui présente des problèmes de lenteurs.
Parmi les requêtes lentes, j'en ai une de la forme :
SELECT * FROM Table1 WHERE Champ1 IN (SELECT Champ2 FROM Table2 WHERE Champ2_2 = 1)
Où Table1 comporte plusieurs millions de lignes, la requête 'SELECT Champ2 FROM Table2 WHERE Champ2_2 = 1' ne renvoie que 5 lignes et le résultat ne comporte que 30 lignes.
J'ai effectué deux tentatives d'amélioration différentes:
1 2
| WITH Table3 AS (SELECT Champ2 FROM Table2 WHERE Champ2_2 = 1)
SELECT * FROM Table1 WHERE Champ1 IN (SELECT Champ2 FROM Table3) |
Les performances sont à peu près identiques
J'ai ensuite essayé avec une jointure:
SELECT Table1.* FROM Table1 INNER JOIN Table2 ON Table1.Champ1 = Table2.Champ2 WHERE Table2.Champ2_2 = 1
Les performances sont un peu meilleures.
Enfin, j'ai essayé un truc du genre(Vous me comprendrez):
String maChaine = Join(Result("SELECT Champ2 FROM Table2 WHERE Champ2_2 = 1"), ","))
Ensuite
SELECT * FROM Table1 WHERE Champ1 IN (" + maChaine + ")
Et là, les performances sont très bonne(environ 3 à 10 fois meilleures que les solutions précédentes.
C'est à peu près l'inverse que j'aurais imaginé: La solution avec la clause In sous forme de chaîne n'est pas indexée, elle nécessite une boucle pour concaténer la chaîne de caractères... ça n'envoie pas du rêve!
Alors comment peut-elle être plus performante que les autres solutions, je ne comprends pas??
J'ai l'impression que la solution avec 'With' exécute la requête 'SELECT Champ2 FROM Table2 WHERE Champ2_2 = 1' pour chaque ligne??
Peut-on utiliser des hint pour améliorer la solution avec la clause With, en forçant Oracle à ne la calculer qu'une seule fois?
Avez-vous des idées à me proposer, sachant que je ne suis pas dba et que je ne peux pas toucher à la structure de la base de données.
Merci d'avance pour vos réponses et joyeuses fêtes.
Partager