Comment puis-je résoudre des problèmes de performance avec une déclaration SQL Oracle

j'ai deux insert statements, presque exactement les mêmes, qui fonctionnent dans deux schémas différents sur la même instance Oracle. Ce à quoi ressemble la déclaration insert n'a pas d'importance - je suis à la recherche d'une stratégie de dépannage ici.

les deux schémas ont 99% la même structure. Quelques colonnes ont des noms légèrement différents, à part qu'elles sont identiques. Les instructions insert sont presque identiques. Le plan expliquer sur un donne un coût de 6, le plan expliquer sur l'autre donne un coût de 7. Les tables impliquées dans les deux ensembles d'instructions insert ont exactement les mêmes index. Les statistiques ont été recueillies pour les deux schémas.

un insert insère 12 000 enregistrements en 5 secondes.

l'autre insert statement insère 25 000 enregistrements en 4 minutes et 19 secondes.

le nombre d'enregistrements à inscrire est exact. C'est la grande disparité des délais d'exécution qui me trouble. Étant donné que rien ne ressort dans le plan d'explication, comment détermineriez-vous ce qui cause cette disparité dans les runtimes?

(J'utilise Oracle 10.2.0.4 sur une fenêtre Windows).

Edit: le problème a fini par être un plan de requête inefficace, impliquant une fusion cartésienne qui n'a pas besoin d'être fait. L'utilisation judicieuse d'indices d'index et d'un indice de jointure de hachage a résolu le problème. Cela prend maintenant 10 Secondes. Sql Trace / TKProf m'a donné le direction, comme je il m'a montré combien de secondes chaque pas dans le plan a pris, et combien de lignes ont été générées. Ainsi TKPROF m'a montré: -

Rows     Row Source Operation
-------  ---------------------------------------------------
  23690  NESTED LOOPS OUTER (cr=3310466 pr=17 pw=0 time=174881374 us)
  23690   NESTED LOOPS  (cr=3310464 pr=17 pw=0 time=174478629 us)
2160900    MERGE JOIN CARTESIAN (cr=102 pr=0 pw=0 time=6491451 us)
   1470     TABLE ACCESS BY INDEX ROWID TBL1 (cr=57 pr=0 pw=0 time=23978 us)
   8820      INDEX RANGE SCAN XIF5TBL1 (cr=16 pr=0 pw=0 time=8859 us)(object id 272041)
2160900     BUFFER SORT (cr=45 pr=0 pw=0 time=4334777 us)
   1470      TABLE ACCESS BY INDEX ROWID TBL1 (cr=45 pr=0 pw=0 time=2956 us)
   8820       INDEX RANGE SCAN XIF5TBL1 (cr=10 pr=0 pw=0 time=8830 us)(object id 272041)
  23690    MAT_VIEW ACCESS BY INDEX ROWID TBL2 (cr=3310362 pr=17 pw=0 time=235116546 us)
  96565     INDEX RANGE SCAN XPK_TBL2 (cr=3219374 pr=3 pw=0 time=217869652 us)(object id 272084)
      0   TABLE ACCESS BY INDEX ROWID TBL3 (cr=2 pr=0 pw=0 time=293390 us)
      0    INDEX RANGE SCAN XIF1TBL3 (cr=2 pr=0 pw=0 time=180345 us)(object id 271983)

remarquez les lignes où les opérations sont fusionnées JOIN CARTESIAN et BUFFER SORT. Les choses qui m'ont poussé à regarder cela étaient le nombre de lignes générées (plus de 2 millions!) et le temps consacré à chaque opération (par rapport aux autres opérations).

5
demandé sur Mike McAllister 2008-09-19 21:51:09
la source

9 ответов

4
répondu Eddie Awad 2015-09-03 01:48:44
la source

les principaux coupables des ralentissements sont les indices, les contraintes et les déclencheurs oninsert. Faites un test sans autant de ceux-ci que vous pouvez enlever et voir si c'est rapide. Ensuite, présentez-les de nouveau et de voir lequel est à l'origine du problème.

j'ai vu des systèmes où ils laissent tomber les index avant les inserts en vrac et reconstruisent à la fin -- et c'est plus rapide.

2
répondu Lou Franco 2008-09-19 22:05:01
la source

la première chose à réaliser est que, comme la documentation dit , le coût que vous voyez affiché est relatif à un des plans de requête. Les coûts pour 2 explications différentes sont et non comparables. Deuxièmement, les coûts sont basés sur une estimation interne. Aussi dur Qu'Oracle essaie, ces estimations ne sont pas exactes. Surtout pas quand l'optimiseur se comporte mal. Votre situation suggère qu'Il ya deux plans de requête qui, selon Oracle, sont très proches en performance. Mais qui, en fait, fonctionnent très différemment.

l'information réelle que vous voulez examiner est le plan expliquer lui-même. Qui vous dit exactement comment Oracle exécute cette requête. Il a beaucoup de gobbeldy-gook technique, mais ce que vous vous souciez vraiment est de savoir qu'il fonctionne de la partie la plus découpée dehors, et à chaque étape il fusionne selon un d'un petit nombre de règles. Qui vous dira Ce Que fait Oracle différemment dans les deux cas.

et après? Il y a une variété de stratégies pour accorder de mauvaises déclarations. La première option que je suggérerais, si vous êtes dans Oracle 10g, est d'essayer leur SQL tuning advisor pour voir si une analyse plus détaillée indiquera à Oracle l'erreur de ses façons. Il peut ensuite stocker ce plan, et vous utiliserez le plan plus efficace.

Si vous ne pouvez pas le faire, ou si cela ne fonctionne pas, alors vous avez besoin pour entrer dans des choses comme fournir des indices de requête, les contours de requête stockés manuellement, et les semblables. C'est un sujet complexe. C'est là que ça aide d'avoir un vrai DBA. Si vous ne le faites pas , alors vous voudrez commencer à lire la documentation , mais soyez conscient qu'il y a beaucoup à apprendre. (Oracle a aussi une classe de syntonisation SQL qui est, ou du moins était, très bonne. Il n'est pas bon marché.)

1
répondu user11318 2008-09-19 22:15:03
la source

j'ai mis ma liste de choses à vérifier pour améliorer la performance comme une réponse à une autre question:

Favori de réglage des performances de trucs

... Il pourrait être utile comme une liste de contrôle, même si ce n'est pas Oracle.

1
répondu AJ. 2017-05-23 13:27:52
la source

je suis d'accord avec une affiche précédente que SQL Trace et tkprof sont un bon endroit pour commencer. Je recommande également fortement le livre Optimizing Oracle Performance , qui traite des outils similaires pour le traçage de l'exécution et l'analyse de la sortie.

0
répondu Dave Costa 2008-09-19 22:25:00
la source

Trace SQL et tkprof ne sont bons que si vous avez accès à ces outils. La plupart des grandes entreprises pour lesquelles je travaille ne permettent pas aux développeurs d'accéder à quoi que ce soit sous les IDs d'Oracle unix.

je crois que vous devriez être en mesure de déterminer le problème en comprenant d'abord la question qui est posée et en lisant les plans expliquer pour chacune des questions. Souvent, je trouve que la grande différence est qu'il y a des tableaux et des index qui n'ont pas été analysés.

0
répondu 2008-09-23 22:57:49
la source

une autre bonne référence qui présente une technique générale pour l'accord de requête est le livre SQL Tuning de Dan Tow.

0
répondu thoroughly 2008-09-23 23:07:45
la source

quand l'exécution d'un énoncé sql n'est pas comme prévu / désiré, une des premières choses que je fais est de vérifier le plan d'exécution.

le truc est de vérifier des choses qui ne sont pas comme prévu. Par exemple, vous pouvez trouver des scans de table où vous pensez qu'un scan d'index devrait être plus rapide ou vice versa.

Un point où l'optimiseur oracle, parfois, prend un mauvais virage sont les estimations le nombre de lignes d'une étape sera de retour. Si le plan d'exécution attend 2 lignes, mais vous savez que ce sera plus de 2000 lignes, le plan d'exécution est lié à être moins optimale.

deux états pour comparer, vous pouvez évidemment comparer les deux plans d'exécution pour voir où ils diffèrent.

à partir de cette analyse, je propose un plan d'exécution qui, à mon avis, devrait être mieux adapté. Ce n'est pas un plan d'exécution exact, mais juste quelques changements cruciaux, à celui que j'ai trouvé, comme: il devrait utiliser Index X ou une jointure Hash au lieu d'une boucle imbriquée.

ensuite, il faut trouver un moyen de faire en sorte Qu'Oracle utilise ce plan d'exécution. Souvent en utilisant des indices, ou en créant des index additonaux, parfois en changeant L'instruction SQL. Puis bien sûr tester que la déclaration modifiée

) fait encore ce qu'il est censé faire

b )est en fait plus rapide

avec b il est très important de s'assurer que vous testez le cas d'utilisation correcte. Un typique pit fall est la différence entre retourner la première rangée, par rapport à retourner la dernière rangée. La plupart des outils vous montrent les premiers résultats dès qu'ils sont disponibles, sans indication directe, qu'il reste du travail à faire. Mais si votre programme réel doit traiter toutes les lignes avant qu'il ne continue à l'étape suivante du traitement, il est presque hors de propos quand la première ligne apparaît, il est seulement pertinent quand la dernière ligne est disponible.

Si vous trouvez un meilleur plan d'exécution, le la dernière étape est de vous faire base de données réellement l'utiliser dans le programme réel. Si vous avez ajouté un index, cela va souvent fonctionner hors de la boîte. Les indices sont une option, mais peuvent être problématiques si une bibliothèque crée votre énoncé sql, ceux ofte ne supportent pas les indices. Comme un dernier recours, vous pouvez enregistrer et résoudre les plans d'exécution spécifique sql. J'éviterais cette approche, parce que c'est facile de se faire oublier et dans un an ou deux un pauvre développeur se grattera la tête pourquoi la déclaration fonctionne d'une manière que pourrait avoir été winrar avec les données, il y a un an, mais pas avec les données actuelles ...

0
répondu Jens Schauder 2013-12-27 11:38:39
la source

" l'analyse de l'io aussi fortement recommander le livre Optimizing Oracle Performance, qui traite des outils similaires pour le traçage de l'exécution et utrput.

-1
répondu 2009-04-30 15:56:47
la source

Autres questions sur