|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Bonjour ,
je fais des insertions des données qui proviennent d'une autre table via dblink. mails la table cible contient plusieurs milliers de lignes , et j'ai des problèmes de performances , je souhaiterais faire des commit après un certain nombre d’enregistrements insérés ,ci-dessous ma requête . Code :
Toute aide sera la bienvenue , merci . |
||
|
|
00
|
|
|
#2 | ||||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 287 ![]() |
Bonjour,
Avant de pouvoir vous donner un conseil, j’aurai aimé connaitre comment êtes vous arrivé à savoir que "commiter" tous 1000 lignes améliorera la performance de votre select? Cary Millsap: a dit une chose très sensée: ''Why Guess when you can know?'' Pourquoi devinez lorsque vous pouvez savoir ? Aussi, dans ce genre de situations, il vaut mieux diagnostiquer correctement le problème de performance avant de lui apporter par la suite le remède qui lui sied parfaitement. Ceci dit j’ai quelques conseils à vous donner quand même: Si votre table d’insertion n’a ni trigger ni contrainte d’intégrité (FK) pensez alors à utiliser un ''direct path load'' en utilisant le hint /*+ append */. Code :
Code :
Attention ceci représente une solution valable lorsque vous ne faites pas de ''delete'' fréquents sur la table où lorsque vous insérez dans une table vide. En effet le ''direct path load'' insert directement au dessus du High Water Mark et n’utilise aucun espace libre existant dans les blocks de données. Si vous partez d’une table vide, ou si le volume de données à insérer est largement supérieur au volume de données actuel de la table, il vaut mieux alors mettre tous les indexes dans un statut ‘DISABLED’ et faire un ‘rebuild’ après la fin de l’insert. Si vous lisez le nouveau libre de Jonathan Lewis, vous réfléchiriez à plusieurs reprises avant d’utiliser un select *. Je vous conseille alors de remplacer le select * par les colonnes nécessaires à l’insert uniquement. Est-ce que votre table est partitionnée ? d'autres suggestions peuvent être envisagées dans ce cas aussi Enfin, comme je l’ai signalé au début, pensez à tracer votre insert/select via l’event 10046 afin de connaître réellement où se trouve l’origine du ralentissement de votre insert |
||||
|
|
20
|
|
|
#3 | |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Bonjour Mohamed ,
Bravo, c'est ce qu'on appelle par une réponse remplie de bon sens . Effectivement je pensais que les insertions étaient stockées dans les UNDO, c'est pourquoi j'ai pensé qu'en effectuant des commit intermédiaires , j'aurais résolu mon problème mais apparemment non .. . Ceci dit mon contexte est celui ci: Ma table contient déjà des données (des millions de lignes) précédemment enregistrées, elle a aussi des contraintes de Primary key , de Unique Key mais pas de FK . Si je fais un Code :
SELECT * FROM la_table_cible@mon_dblink ; Parraport à vos conseils , je pense que la solution : Citation:
La table cibles sont partitionnée , ma table de destination (celle qui doit contenir les données extraites ) est aussi partitionnée . Merci toujours pour vos conseils si éclairés . |
|
|
|
00
|
|
|
#4 | |||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 287 ![]() |
Citation:
Code :
|
|||
|
|
10
|
|
|
#5 |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Hi Mohamed ,
intéressant , sauf que dans mon cas la table n'a pas été construite avec des index locaux , mais avec un index global, dans ce cas dois je le "disabler" de façon globale et le reconstruire ? ça ne serait pas un traitement lourd pour une table contenant des millions de ligne ??? Merci |
|
|
00
|
|
|
#6 | |
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 287 ![]() |
Citation:
Pour les indexes globaux, cela n'a pas de sens surtout lorsque le volume de données apporté par l'insert est largement inférieur au volume des données avant l'insert. En d'autres mots, si vous insérez 1 million de lignes dans une table qui en contient déjà 10 millions, vous devriez dans ce cas éviter de faire le ''disable'' des indexes avant insert; autrement vous auriez à faire un rebuild d'un index de 11 millions de lignes; ce qui n'est pas négligeable |
|
|
|
10
|
|
|
#7 |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Ok ,
je teste tout ça et je vous fait un feed-back . Merci encore |
|
|
00
|
|
|
#8 | |||
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Hi Mohamed ,
Je reviens encore avec mon problème de performance , après avoir suivi vos conseils j'ai modifié mon script comme ci-dessous: Code :
Citation:
Auriez-vous d'autres conseils intéressants à me donner pour optimiser cette requête , merci . |
|||
|
|
00
|
|
|
#9 | ||||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 287 ![]() |
Bonjour
Pourquoi utilisez-vous du SQL dynamique? Le SQL statique n'est pas possible? Puisque vous êtes encore en environement de TEST, faites ce qui suit Code :
Code :
Avec le fichier trace généré vous allez savoir où est épuisé le temps d'execution de l'insert/select |
||||
|
|
10
|
|
|
#10 |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Hi Mohamed ,
puis je savoir quelle est la conséquence en ajoutant la ligne ci-dessous Code :
ALTER session SET events '10046 trace name context forever, level 12'; Pensez-vous qu'il serait plus performant d'utiliser le sql normal (statique) au sql dynamique ? pour ce qui est de la restriction de la partition p1 , la vue fait déjà une restriction sur la partition où est hébergée la table cible . Merci |
|
|
00
|
|
|
#11 | ||
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 287 ![]() |
Citation:
Citation:
Il existe de bonnes habitudes en Oracle qu'il convient d'adopter aussi longtemps que cela est possible. Parmi ces bonnes habitudes c'est de n'utiliser le SQL dynamique que si le SQL statique n'est pas possible. L'explication se trouve dans ce site et dans d'autres également. Il suffit de chercher. Dans quel environnement faites vous votre insert/select? |
||
|
|
10
|
|
|
#12 | |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Ok ,
Je travaille sur Citation:
Pour ce qui du fichier trace généré dans user_dump_test je l'ai localisé et sachant que ma requête prends des heures et heures pour s'exécuter , pensez-vous que le résultat provisoire qu'il a généré peut nous en dire long déjà sur les problèmes de performance que je rencontre ? Merci |
|
|
|
00
|
|
|
#13 | |
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 287 ![]() |
Citation:
|
|
|
|
00
|
|
|
#14 |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Hi Mohamed ,
en pièce-jointe , le fichier trace "provisoire" généré . Merci |
|
|
00
|
|
|
#15 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 316 ![]() |
Voilà le profile de votre traitement qui vous indique où le temps passe.
|
|
|
00
|
|
|
#16 |
|
Expert Confirmé Sénior
![]() ![]() Marius NituIngénieur développement logiciels Inscription : octobre 2007 Messages : 3 316 ![]() |
|
|
|
00
|
|
|
#17 |
|
Membre expérimenté
![]() Mohamed HouriInscription : mars 2010 Messages : 287 ![]() |
98% de votre temps est passé dans "SQL*Net message from dblink [idle]" comme vous pouvez le constater via le fichier html attaché.
Vous devriez limiter le volume de données transférées entre les deux bases de données. Il est vrai que nous ne savons pas qu'est ce qui se cache derrière Combien de lignes envisagez-vous d’insérer avec ce select? Il va falloir aller dans la base distante et faire un examen minutieux de ce select. Peut-être qu’il y a un moyen d’améliorer la performance du select qui se cache derrière ce qui semble être une vue. Essayez de limiter le select à une dizaine de lignes (where rownum<10) et voir si l’insert/select s’exécute quand même très vite ou pas juste pour confirmer que le volume de données échangé entre les deux bases représente le problème à traiter |
|
|
00
|
|
|
#18 | |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
@mnitu
Merci pour le output en HTML . @Mohamed , la vue renvoie en moyenne 1 million 800 mille lignes . Je teste la requête avec un Citation:
Et je vous fait le feed-back . Merci |
|
|
|
00
|
|
|
#19 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Salut !
Ca parait un peu barbare comme procédé... C'est un fonctionnement de prod, où tu fais ça pour te créer de la donnée ? Peut être qu'exporter d'un côté, charger de l'autre serait plus efficace ?
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
00
|
|
|
#20 |
|
Candidat au titre de Membre du Club
![]() Inscription : juillet 2007 Messages : 63 ![]() |
Bonjour pacmann ,
en effet au final c'est avec la prod que je dois faire cette manipulation, et je n'ai pas le droit de créer une table (même temporaire) . Si vous m'expliquez comment faire le dump d'une vue ... je suis preneur, car comme vous le constaterez je fais le lien avec une vue et non avec une table directement . |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com