Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour à tous,
Lors de la génération d'un rapport dans mon application, le temps pour exécuter la requete prend 10 minute pour générer une ligne...
j'ai fait le débugage et voici la requête, et si vous avez des idées pour l'optimiser :
SELECT SUM(c.C1 * c.C2) C3, (c.C5) C51, (c.C6) C61, (c.C7) C71, c.C8, c.C9, cp.C10, (c.C11) C111 FROM T1 c, T2 t, T3 cp, T4 tr WHERE (c.C14 < To_Date('04/01/2009', 'mm/dd/yyyy')) AND ((c.C15 = '1')) AND ((c.C16 IN (SELECT C30 FROM T5 WHERE C31 = 200))) AND ((c.C18 = '4471')) AND ((c.C19 = 'EUR')) AND ((c.C20 = 'EUR')) AND ((tr.C21 = c.C21)) AND ((c.C23 = t.C24(+))) AND ((c.C50 = cp.C55)) AND ((cp.C60 = c.C70)) GROUP BY c.C111, c.C51, c.C61, c.C71, c.C8, c.C9, cp.C10
Merci pour vos aides
Dernière modification par mattdamon (07-05-2009 12:08:50)
Hors ligne
Bonjour, as-tu testé dans un requêteur SQL pour voir si le temps d'exécution est le même ? Si oui, bah, PB n'y est pour rien... il faut optimiser la base (index) ou la requête...
Nième rappel pour la balise code : le langage plsql n'est pas défini... cf Coloration des scripts dans les messages
Hors ligne
erasorz a écrit:
Bonjour, as-tu testé dans un requêteur SQL pour voir si le temps d'exécution est le même ? Si oui, bah, PB n'y est pour rien... il faut optimiser la base (index) ou la requête...
Nième rappel pour la balise code : le langage plsql n'est pas défini... cf Coloration des scripts dans les messages
Oui bien sûre, j'ai récupéré la requête et je l'ai exécutée sue PL/SQL developper.... et le temp d'exécution est toujours le même....
En parlant de l'optimisation de la requête, j'ai enlevé le GROUP BY et j'ai mis * dans la select et dans ce cas le temp est inférieur...
d'après vous c'est quoi le problème ? Est-ce que le problème est liée à la group by ou quoi ?
J'ai passé beaucoup de temps pour l'optimiser, mais j'ai rien à optimiser dans cette requête.
Merci
Dernière modification par mattdamon (07-05-2009 12:21:36)
Hors ligne
Fais un explain plan dans PLSQL Developper: Tu verras directement quels sont les points de ta requête qui clochent (Non utilisation d'indexes par exemple). Déjà, je pense que tu devrais regarder si ta clause "IN" n'est pas en partie la cause de tes problèmes. Maintenant, c'est difficile de se faire une idée sans avoir la structure et la taille de ta BDD sous les yeux
Hors ligne
foon a écrit:
Fais un explain plan dans PLSQL Developper: Tu verras directement quels sont les points de ta requête qui clochent (Non utilisation d'indexes par exemple). Déjà, je pense que tu devrais regarder si ta clause "IN" n'est pas en partie la cause de tes problèmes. Maintenant, c'est difficile de se faire une idée sans avoir la structure et la taille de ta BDD sous les yeux
Merci foon pour ta réponse,
Je manipule cette option de Pl/SQL developer pour la première fois, est-ce que peux-tu expliquer moi le problème de quoi il s'agit :
Hors ligne
Difficile à dire sans la requête réelle et les desc des tables, ainsi que leur volumétrie.
Cependant, il faut regarder le "cost" et la "cardinality" des requêtes pour savoir où porter ton optimisation. De même, la présence de "full access" indique que tu scannes une table sans passer par des indexes, ce qui peut être pénalisant. En l'occurence, dans ton cas, il n'y a pas de full access, donc ce n'est pas de ce coté qu'il faut chercher.
Pour la cardinality, seule celle de l'indexe NDX_COMPTA_PORTEF_CP est élevée par rapport aux autres (115), mais comme le cost ne l'est pas (2), ça ne vient probablement pas de là.
Par contre, le cost du 3ème "Nested loops" en partant du haut est à 78. C'est de ce coté là que je pousserai mes investigations. A voir s'il s'agit d'une jointure de table peu judicieuse, et surtout laquelle. Seul toi peux le savoir, vu que tu as la base de données sous les yeux.
Sinon, n'oublies pas qu'il est possible de faire des sous-requêtes directement dans la clause FROM en PL-SQL, ça peut être utile car ceci permet d'effectuer ton SELECT final sur un nombre plus restreint d'enregistrements. Attention aussi que tes calculs (SUM) ne se fassent pas sur un trop grand nombre d'enregistrements: les fonctions ORACLE peuvent être très coûteuses en temps de traitement si elles sont mal utilisées.
Hors ligne
Bonjour,
Petite astuce afin de visualiser l'exécution de la requête :
Sous session sql (comme sqlplus ou telnet ) taper le code suivant
set autotrace on
Puis taper requête. Il ne reste plus qu'à analyser le bloc "Statistics".
Autre remarque :
Utiliser la fonction EXISTS plutôt que IN si dans la requête du IN il y a beaucoup d'enregistrement inutiles ains on aurait :
SELECT SUM(c.C1 * c.C2) C3, (c.C5) C51, (c.C6) C61, (c.C7) C71, c.C8, c.C9, cp.C10, (c.C11) C111 FROM T1 c, T2 t, T3 cp, T4 tr WHERE (c.C14 < To_Date('04/01/2009', 'mm/dd/yyyy')) AND ((c.C15 = '1')) [b] AND (EXISTS (SELECT C30 from T5 WHERE C31 = 200 and c.C16 = C30))[/b] AND ((c.C18 = '4471')) AND ((c.C19 = 'EUR')) AND ((c.C20 = 'EUR')) AND ((tr.C21 = c.C21)) AND ((c.C23 = t.C24(+))) AND ((c.C50 = cp.C55)) AND ((cp.C60 = c.C70)) GROUP BY c.C111, c.C51, c.C61, c.C71, c.C8, c.C9, cp.C10
Bon courage
Hors ligne
Bonjour
Il faut mettre toutes les conditions les plus restrictives en premier.
SELECT SUM(c.C1 * c.C2) C3, (c.C5) C51, (c.C6) C61, (c.C7) C71, c.C8, c.C9, cp.C10, (c.C11) C111 FROM T1 c, T2 t, T3 cp, T4 tr WHERE AND ((c.C15 = '1')) AND ((c.C18 = '4471')) AND ((c.C19 = 'EUR')) AND ((c.C20 = 'EUR')) AND ((tr.C21 = c.C21)) AND ((cp.C60 = c.C70)) AND ((c.C50 = cp.C55)) AND (c.C14 < '04/01/2009') AND ((c.C23 = t.C24(+))) AND (EXISTS (SELECT C30 from T5 WHERE C31 = 200 and c.C16 = C30)) GROUP BY c.C111, c.C51, c.C61, c.C71, c.C8, c.C9, cp.C10
Ce devrait être plus rapide
Hors ligne