Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
#26 11/05/2012 17:19:22
- rjuju
- Administrateur
Re : bulk collect
Quel est le message d'erreur renvoyé ?
Avez-vous regardé dans la vue pg_stat_activity s'il n'y avait pas des choses étranges ?
Julien.
https://rjuju.github.io/
Hors ligne
#27 11/05/2012 17:21:23
- karthus
- Membre
Re : bulk collect
Je n'ai aucun message d'erreur , au bout de 10min j'ai fais un ctrl - C , pour 1 update je pense que sa fait beaucoup. Oui je l'ai fais , rien d'étrange , je peux faire un delete mais pas de drop , ni utiliser mes fonctions , par contre les autres tables oui.
Hors ligne
#28 11/05/2012 17:36:53
- rjuju
- Administrateur
Re : bulk collect
Il y a forcément une transaction qui bloque.
Vous pouvez redémarrer votre service postgres si personne ne l'utilise pour être certain de couper toutes les connexions.
Julien.
https://rjuju.github.io/
Hors ligne
#29 11/05/2012 17:46:49
- karthus
- Membre
Re : bulk collect
Il ne me reste que 15min donc je vais m'occuper d'autre chose , je verrais sa après le week end.
Hors ligne
#30 14/05/2012 10:22:04
- karthus
- Membre
Re : bulk collect
J'ai trouvé la table qui me bloque, il s'agit de t_ref_ett , en utilisant la table pg_locks j'obtiens:
relname | mode | granted | pid
-----------------------------------+--------------------------+---------+-------
pk_t_entcdecli | AccessShareLock | t | 6320
pg_class_relname_nsp_index | AccessShareLock | t | 13590
t_ref_ett | AccessExclusiveLock | f | 29689
pk_t_ref_ett | AccessShareLock | t | 6320
pg_locks | AccessShareLock | t | 13590
ak_cle_2_t_entcde | AccessShareLock | t | 6320
pg_class | AccessShareLock | t | 13590
t_ref_ett | AccessShareLock | f | 11354
tmp_entcdecli | AccessShareLock | t | 6320
t_ref_ett | AccessShareLock | t | 6320
ak_cle_unicite_t_ref_et | AccessShareLock | t | 6320
t_ref_ett | AccessExclusiveLock | f | 22781
t_ref_ett | AccessExclusiveLock | f | 9346
t_entcdecli | AccessShareLock | t | 6320
pg_class_oid_index | AccessShareLock | t | 13590
Hors ligne
#31 14/05/2012 10:48:16
- karthus
- Membre
Re : bulk collect
La table sur laquelle je travaille utilise cette table de référence t_ref_ett , tout bêtement , j'ai donc fait un kill car apparemment il y avait une procédure stockée qui ne s'était pas arrété.
Hors ligne
#32 14/05/2012 15:04:13
- karthus
- Membre
Re : bulk collect
En essayant une autre méthode j'ai remarqué que mon cursor met 20min au moins les 25 pour se créer , et le lire ligne par ligne puis de faire un update à chaque ligne d'une colonne état qui par la suite servira à savoir s'il faut faire un traitement sur cette ligne. Est-ce normal que ce soit aussi long?
Hors ligne
#33 14/05/2012 15:26:02
- Marc Cousin
- Membre
Re : bulk collect
Bonjour,
J'ai du mal à comprendre: c'est le select générant le curseur qui met 20 minutes pour se créer ? Que voulez-vous dire par là ?
Sinon, vu qu'on n'a qu'un exemple assez vague de ce que vous faites réellement, le bout de code qui fait les mises à jour de la table ne serait pas dans un sous-bloc begin/end (ou une fonction distincte?) avec un bloc d'exception ?
Marc.
Hors ligne
#34 14/05/2012 15:37:08
- karthus
- Membre
Re : bulk collect
Voici mon code très barbare , la fonction met 26min pour s'executer , suite à cela dans ma table temporaire les colonnes concerné auront comme etat_int la valeur 3 , je fais donc un copy ... to , puis en copy ... from (3sec au total pour 72000 , les 2 copy au total ) mais le curseur est beaucoup trop long. Si vous avez besoin d'autres infos...Par contre je ne pense pas que je laisserai le code longtemps sur le forum.
/* delete */
Dernière modification par karthus (22/05/2012 09:25:26)
Hors ligne
#35 14/05/2012 15:45:42
- Marc Cousin
- Membre
Re : bulk collect
Sur l'update, je vois déjà 2 problèmes possibles «évidents»:
- Les OID ne sont pas indexés par défaut. Votre where oid=rowids fait un seqscan, à moins que vous n'ayez mis un index ? (vu que vous créez un autre index plus haut pour cette table, et qu'elle a tmp_ dans le nom, je préfère poser la question)
- Les OID ne doivent plus être utilisés dans des tables utilisateur (c'est déconseillé).
Sinon, avez vous regardé le temps d'exécution, et le plan, du select utilisé par le curseur ? Si oui, vous pouvez le poster aussi.
Marc.
Hors ligne
#36 14/05/2012 15:57:57
- karthus
- Membre
Re : bulk collect
Effectivement le problème vient de l'update , j'ai exécuté ma fonction sans , le résultat est de 1 sec.
Le seul index que j'ai est celui de la fonction qui crée au début et supprimé à la fin.
Pour l'oid il y était de base donc je préfère le laisser au moins pour l'instant , s'il faut faire sans je verrai plus tard si je peux l'enlever.
Et pour le explain j'obtiens:
Merge Join (cost=44791.38..47440.74 rows=119009 width=139)
Merge Cond: ((t_ref_ett.cod_typett = tmp_entcdecli.num_typett) AND (t_ref_ett.num_bu = tmp_entcdecli.num_bu) AND (t_ref_ett.num_ett = tmp_entcdecli.num_ett))
-> Sort (cost=17.26..17.74 rows=193 width=39)
Sort Key: t_ref_ett.cod_typett, t_ref_ett.num_bu, t_ref_ett.num_ett
-> Seq Scan on t_ref_ett (cost=0.00..9.93 rows=193 width=39)
-> Sort (cost=44774.13..45138.59 rows=145787 width=160)
Sort Key: tmp_entcdecli.num_typett, tmp_entcdecli.num_bu, tmp_entcdecli.num_ett
-> Seq Scan on tmp_entcdecli (cost=0.00..8351.34 rows=145787 width=160)
Filter: (etat_int <> 1::numeric)
Hors ligne
#37 14/05/2012 16:05:56
- karthus
- Membre
Re : bulk collect
Le problème vient du WHERE OID = ROWIDS; mais comment faire autrement? Je dois bien faire un update ligne par ligne , et sur les bonnes tant qu'à faire.
Hors ligne
#38 14/05/2012 16:37:58
- rjuju
- Administrateur
Re : bulk collect
Il faudrait utiliser la clé primaire de la table pour effectuer l'update, ou ajouter un index à l'oid.
Dernière modification par rjuju (14/05/2012 16:38:45)
Julien.
https://rjuju.github.io/
Hors ligne
#39 14/05/2012 16:44:58
- karthus
- Membre
Re : bulk collect
Justement c'est là où c'est drôle , car il n'y en a pas. Aucune clé primaire , aucune contrainte d'unicité , les tables temporaires sont juste des colonnes qu'on insérera dans la table principale en ajoutant une colonne qui contiendra la clé primaire , donc inutile pour moi à ce stade.
Pour l'index j'ai mis CREATE INDEX I_TMP_ENTCDECLI on TMP_ENTCDECLI(NUM_ETT, NUM_BU, NUM_TYPETT, NUM_CDECLI, DAT_CREPROD,OID).
La fonction vient juste de finir , cela m'a pris 9,5min , sa moins de la moitié du temps initial.
Dernière modification par karthus (14/05/2012 16:47:00)
Hors ligne
#40 14/05/2012 16:57:25
- Marc Cousin
- Membre
Re : bulk collect
Vous pouvez essayer encore plus agressif, puisque je présume que vous n'aurez qu'un seul de ces traitements à la fois:
rajoutez TMP_ENTCDECLI.ctid dans votre curseur, et utilisez ce champ pour la mise à jour. C'est l'adresse physique de l'enregistrement. Évidemment, après avoir fait l'update l'adresse de l'enregistrement risque de changer, mais vu l'exemple, ça ne devrait pas poser problème.
Marc.
Hors ligne
#41 14/05/2012 16:58:54
- Marc Cousin
- Membre
Re : bulk collect
Évidemment, dans ce cas, l'update devient
UPDATE TMP_ENTCDECLI
SET ETAT_INT = 3
WHERE ctid = mon_ctid_que_j_ai_recupere_dans_mon_fetch
Marc.
Hors ligne
#42 14/05/2012 17:10:01
- karthus
- Membre
Re : bulk collect
Pourquoi n'y était-il pas de base sur le script oracle alors? Il n'y en a pas besoin?
Désolé mais bon je débute , et même après avoir lu la doc sur l'index j'ai un peu de mal à accrocher.
Hors ligne
#43 14/05/2012 17:17:20
- Marc Cousin
- Membre
Re : bulk collect
Sur le script oracle, il ne pouvait pas y être, il n'y a pas d'oid. Je ne sais pas comment fonctionnait le script oracle, mais je présume que ça devait être similaire, il devait y avoir une clé quelconque sur la table pour retrouver l'enregistrement.
Marc.
Hors ligne
#44 14/05/2012 17:23:18
- karthus
- Membre
Re : bulk collect
C'est exactement la même table , et il y a un oid , ou plutôt un rowid , d'où le WHERE OID = ROWIDS; car à la base c'était WHERE ROWID = ROWIDS; enfin bref. Je testerai demain si possible avec le contenu total de la base oracle , soit des millions de lignes et je verrais le résultat. En tout cas merci beaucoup pour votre patiente et votre aide.
PS: 72000 insert en 591445ms ( soit 9,8min ) au lieu de ~27min
Dernière modification par karthus (14/05/2012 17:24:48)
Hors ligne
#45 14/05/2012 17:33:48
- Marc Cousin
- Membre
Re : bulk collect
ben le rowid correspond exactement au ctid dont je parle au dessus. À la différence que sous PostgreSQL un update peut modifier un ctid, alors que le rowid est conservé sous Oracle.
Marc.
Hors ligne