|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Bonjour,
Je rencontre de gros problèmes de performances avec une de mes procs. Voilà résumé le problème : Le gros de cette proc est d'insérer dans une table via un curseur. Comme vous pouvez le voir plus bas, une jointure a été supprimée (AND ACTNAIRE_NOMI.CD_VALEUR = @CD_VALEUR). Cette jointure apparaissait à plusieurs endroits de la proc, et depuis les performances ont chuté. Il n'y avait pas d'index portant sur cette colonne mais pourtant les perf étaient bonnes. Mais depuis qu'on a supprimé cette jointure, sans toucher aux indexs, les perfs ont chuté. Pouvez-vous m'aider ? Merci Pour les courageux je peux envoyer le script complet de la proc Exemple d'un bout de la proc : Code :
|
||
|
|
00
|
|
|
#2 |
![]() ![]() |
Il faudrait voir le SHOWPLAN ainsi que la définition des indexes sur les deux tables pour voir ce qui ce passe.
Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
|
|
00
|
|
|
#3 |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
J'ai justement un problème avec le showplan.
J'essaie de l'obtenir dans SQL Advantage et j'ai le message suivant quand j'execute le script de ma proc : DECLARE CURSOR must be the only statement in a query batch. Et du coup je n'arrive pas à avoir mon plan... Que faire ? |
|
|
00
|
|
|
#4 | ||
![]() ![]() |
Soit il faut exécuter la proc elle-même avec le SHOWPLAN, soit il faut splitter le code en deux partie et executer le "DECLARE ... CURSOR" séparément. Dans isql cela fait:
Code :
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
||
|
|
00
|
|
|
#5 | |||
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Citation:
Voila à quoi ressemble mon script : set showplan on set statistics io on go ...code... go declare cursor for select go reste du code go et j'obtiens toujours ceci : QUERY PLAN FOR STATEMENT 1 (at line 1). STEP 1 The type of query is SET OPTION ON. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 3: Total estimated I/O cost for statement 1 (at line 1): 0. QUERY PLAN FOR STATEMENT 2 (at line 2). STEP 1 The type of query is SET STATISTICS ON. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 3: Total estimated I/O cost for statement 2 (at line 2): 0. QUERY PLAN FOR STATEMENT 3 (at line 3). STEP 1 The type of query is SET OPTION ON. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 3: Total estimated I/O cost for statement 3 (at line 3): 0. Server Message: Number 7344, Severity 15 Server 'TIT1_PAR_TST_SQL', Line 122: DECLARE CURSOR must be the only statement in a query batch. et ensuite plein de messages d'erreurs pour des variables non déclarées mais qui l'ont pourtant été dans la première partie du code... As-tu une idée ? |
|||
|
|
00
|
|
|
#6 |
![]() ![]() |
Est-ce que SQLAdvantage connait le "go" comme isql?
Est-ce qu'il y a bien un "go" après le declare ... cursor, et PAS de declare ... cursor dans le batch suivant? Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
|
|
00
|
|
|
#7 | |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Citation:
En fait il y a deux curseurs, l'autre est déclaré par la suite. Le code a donc cette forme : set showplan on set statistics io on go ...code... go declare cursor for select go code go declare cursor for select go reste du cide go et j'obtiens toujours Line 122: DECLARE CURSOR must be the only statement in a query batch. Sachant que la ligne 122 est le declare du 1er curseur. |
|
|
|
00
|
|
|
#8 |
![]() ![]() |
Le fait que l'erreur indique la ligne 122 indique que le "go" n'a pas l'air d'être pris en compte comme séparateur de batch.
Je n'utilise pas SQLAdvantage (sqsh sous Unix/Linux), donc je ne peux malheureusement pas donner plus d'info à ce niveau là... Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
|
|
00
|
|
|
#9 | |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Citation:
select * from X go sous Advantage, il ne rale pas et execute bien ma requête. |
|
|
|
00
|
|
|
#10 |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Bon j'ai du mieux, j'ai réussi à identifier la sous requête qui gène :
SELECT @ID_ACTNAIRE = ACTNAIRE.ID_ACTNAIRE, @ID_ACTNAIRE_NOMI = ACTNAIRE_NOMI.ID_ACTNAIRE, @NB_ACT_VS_OLD = ACTNAIRE_NOMI.NB_ACT_VS, @NB_ACT_VP_OLD = ACTNAIRE_NOMI.NB_ACT_VP FROM ACTNAIRE, ACTNAIRE_NOMI WHERE ACTNAIRE.ID_ASS_GEN = @ID_ASS_GEN AND ACTNAIRE.ID_NOMINATIF = @ID_NOMINATIF AND ACTNAIRE_NOMI.ID_ASS_GEN = @ID_ASS_GEN AND ACTNAIRE_NOMI.ID_ACTNAIRE = ACTNAIRE.ID_ACTNAIRE AND ACTNAIRE_NOMI.ID_TYPE_PROP = @ID_TYPE_PROP -- AND ACTNAIRE_NOMI.CD_VALEUR = @CD_VALEUR Quand la dernière ligne est commentée j'obtiens le plan suivant : QUERY PLAN FOR STATEMENT 6 (at line 81). STEP 1 The type of query is SELECT. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC Using I/O Size 16 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. FROM TABLE ACTNAIRE Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 383: Total estimated I/O cost for statement 6 (at line 81): 88220. Si elle n'est pas commentée : QUERY PLAN FOR STATEMENT 6 (at line 81). STEP 1 The type of query is SELECT. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC Using I/O Size 16 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. FROM TABLE ACTNAIRE Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 383: Total estimated I/O cost for statement 6 (at line 81): 13404. Donc mise à part la jointure en plus, je n'arrive pas à comprendre d'où vient une telle différence au niveau des io ?? |
|
|
00
|
|
|
#11 |
![]() ![]() |
Question basique déjà : pourquoi passez-vous par un curseur ???
__________________
Sr DBA Oracle / Sybase / MS-SQL / DB2 / Informix / Postgresql Administrateur SAP Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums ! |
|
|
00
|
|
|
#12 | |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Citation:
Les curseurs ne sont-ils pas censés être performants maintenant ? Peut-on systématiquement les remplacer par autre chose de mieux ? Dernière question : est-il possible d'optimiser le petit bout de code posté plus haut compte tenu de ce que j'ai dit (disparition d'une jointure) ? |
|
|
|
00
|
|
|
#13 | |
![]() ![]() |
Citation:
Il faut bien voir que le message est du nombre d'IO estimé, pas du nombre d'IO effectif pour la requète. Pour avoir le nombre d'IO effectif il faut voir l'output de SET STATISTICS IO ON à la fin de l'exécution de la requète. On peut aussi analyser les données utilisées par l'optimiseur en enablant les trace flags 302 et 310: cela donne des informations sur toutes les décisions prisent par l'optimiseur... Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
|
|
|
00
|
|
|
#14 | |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Citation:
Rajouter les trace flags n'a rien changé au plan, il n'y a aucune info supplémentaire rajoutée. Est-ce possible ? Merci pour l'aide en tout cas, c'est très sympa. |
|
|
|
00
|
|
|
#15 | ||
![]() ![]() |
Voici un exemple - j'utilise sqsh comme client, mais isql devrait avoir le même comportement:
Code :
En ce qui concerne les trace flags 302 et 310 ils devraient donner un output très volumineux, mais il est possible qu'il faille avoir "sa_role" pour pouvoir y avoir accès. Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
||
|
|
00
|
|
|
#16 | |||
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Citation:
|
|||
|
|
00
|
|
|
#17 |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
J'ai une question subsidiaire :
Que signifie exactement cette syntaxe en gras dans le résultat d'un showplan : STEP 1 The type of query is UPDATE. The update mode is direct. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC CD_VALEUR ASC ID_TYPE_PROP ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. TO TABLE ACTNAIRE_NOMI Using I/O Size 2 Kbytes for data pages. Merci |
|
|
00
|
|
|
#18 | ||
![]() ![]() |
Cela signifie que l'optimiseur utilise les quatres cles pour se positioner dans la table.
Prenons un exemple: Si on a un indexe comme ceci: Code :
Michael PS. je ne suis pas très satisfait de mon explication, mais j'ai parfois un peu de peine à traduire les concepts que je connais bien en anglais (p.ex. "the leading columns of the index..."). J'espère que c'est quand même compréhensible!
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
||
|
|
00
|
|
|
#19 |
|
Invité de passage
![]() Inscription : juin 2006 Messages : 27 ![]() |
Bon, je résume ma situation desespérée...
Une proc s'est mise à avoir des performances complètement dégradées suite à la suppression d'une jointure dans les requêtes où elle apparait (jointure sur CD_VALEUR). Cette proc est asse longue, mais en executant le show plan avec et sans jointure je n'obtiens que les seules différences suivantes (les différences en gras) : pour le code : delete ACTNAIRE_NOMI from #modif where #modif.ID_ASS_GEN = ACTNAIRE_NOMI.ID_ASS_GEN and #modif.ID_ACTNAIRE = ACTNAIRE_NOMI.ID_ACTNAIRE and #modif.ID_TYPE_PROP = ACTNAIRE_NOMI.ID_TYPE_PROP --and #modif.CD_VALEUR = ACTNAIRE_NOMI.CD_VALEUR -------------------------------------------------------------------------- QUERY PLAN FOR STATEMENT 5 (at line 98). STEP 1 The type of query is DELETE. The update mode is deferred. FROM TABLE #modif Nested iteration. Table Scan. Forward scan. Positioning at start of table. Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. TO TABLE ACTNAIRE_NOMI Using I/O Size 2 Kbytes for data pages. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 118: Total estimated I/O cost for statement 5 (at line 98): 3054. au lieu de QUERY PLAN FOR STATEMENT 5 (at line 98). STEP 1 The type of query is DELETE. The update mode is deferred. FROM TABLE #modif Nested iteration. Table Scan. Forward scan. Positioning at start of table. Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC CD_VALEUR ASC ID_TYPE_PROP ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. TO TABLE ACTNAIRE_NOMI Using I/O Size 2 Kbytes for data pages. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 118: Total estimated I/O cost for statement 5 (at line 98): 3054. ------------------------------------------------------------------------- Pour le select vu plus haut dans le topic : QUERY PLAN FOR STATEMENT 6 (at line 81). STEP 1 The type of query is SELECT. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC Using I/O Size 16 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. FROM TABLE ACTNAIRE Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 383: Total estimated I/O cost for statement 6 (at line 81): 88220. au lieu de QUERY PLAN FOR STATEMENT 6 (at line 81). STEP 1 The type of query is SELECT. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC Using I/O Size 16 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. FROM TABLE ACTNAIRE Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. Server Message: Number 3630, Severity 10 Server 'TIT1_PAR_TST_SQL', Line 383: Total estimated I/O cost for statement 6 (at line 81): 13404. ------------------------------------------------------------------------- Pour l'update suivant update ACTNAIRE_NOMI set NB_ACT_VS = @NB_ACT_VS, NB_ACT_VP = @NB_ACT_VP where ID_ASS_GEN = @ID_ASS_GEN and ID_ACTNAIRE = @ID_ACTNAIRE -- and CD_VALEUR = @CD_VALEUR and ID_TYPE_PROP = @ID_TYPE_PROP QUERY PLAN FOR STATEMENT 26 (at line 292). STEP 1 The type of query is UPDATE. The update mode is direct. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. TO TABLE ACTNAIRE_NOMI Using I/O Size 2 Kbytes for data pages. au lieu de : QUERY PLAN FOR STATEMENT 26 (at line 292). STEP 1 The type of query is UPDATE. The update mode is direct. FROM TABLE ACTNAIRE_NOMI Nested iteration. Using Clustered Index. Index : PK_ACTNAIRE_NOMI Forward scan. Positioning by key. Keys are: ID_ASS_GEN ASC ID_ACTNAIRE ASC CD_VALEUR ASC ID_TYPE_PROP ASC Using I/O Size 2 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. TO TABLE ACTNAIRE_NOMI Using I/O Size 2 Kbytes for data pages. ------------------------------------------------------------------------- Sachant que l'index PK_ACTNAIRE_NOMI utilisé dans ces requêtes est défini comme ceci : PK_ACTNAIRE_NOMI | clustered, unique located on default | ID_ASS_GEN, ID_ACTNAIRE, CD_VALEUR, ID_TYPE_PROP Je suis vraiment perdu, je ne comprends pas comment je peux récupérer cette perte de performances (la proc met maintenant plus de trois fois le temps initial) Quelqu'un peut-il me sauver ? |
|
|
00
|
|
|
#20 | |
![]() ![]() |
Citation:
Si CD_VALEUR ne doit absolument PAS être utilisé dans la clause WHERE alors la solution serait probablement de modifier la composition de l'index, ou d'en créer un deuxième. Mais avant de faire cela il faudrait faire une analyse plus complète de la problématique, et il est tout à fait possible que la proc puisse être modifiée pour avoir un meilleur comportement global (mais pour ce faire il faut déjà avoir une bonne idée de la structure de la base, des tables utilisées, de l'objectif à atteindre, etc - pas toujours facile pour un problème non-trivial dans ce genre de forum...) Michael
__________________
Michael Peppler Membre de TeamSybase - www.teamsybase.com "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com