IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Oracle Discussion :

[PLSQL]Suppression de plus de 100000 enregistrements


Sujet :

Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 19
    Par défaut [RESOLU][PLSQL]Suppression de plus de 100000 enregistrements
    Bonjour,

    Afin de créer une fonction d'archivage sur ma base, j'essaie de créer un script d'ajout dans un autre schéma et de suppression dans le schéma de production. Mais, voilà, j'ai un premier problème qui me dit que mes rollbacks segments sont trop petits. Ok, j'essaie donc de créer un mini-script pour contourner le problème et supprimer les lignes petit à petit. Je ne sais ps s'il est judicieux sur tous les points mais le voici quand même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    declare
      cursor CURS_PICKDETAIL is 
          select count(*) from PICKDETAIL where EXPORTFLAG = 'E';
      NbPickDetail VARCHAR2(50);
    begin
      LOOP
        Open CURS_PICKDETAIL;
        Fetch CURS_PICKDETAIL into NbPickDetail;
        close CURS_PICKDETAIL;
        Exit when NbPickDetail = 0;
     
        set transaction use rollback segment RBSPEC;
        delete from WMSP.PICKDETAIL
        where EXPORTFLAG = 'E'
        and rownum<1000;
        commit;
      END LOOP;
    End;
    Mais, hélas, j'ai maintenant un nouveau problème. J'ai le message suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ORA-08102: index key not found, obj# 21869, dba 50406478 (2)
    ORA-06512: at line 13
    J'ai cherché à savoir quel était cet index. C'est un index existant sur ma table PICKDETAIL. Je ne comprends pas pourquoi j'ai ce message. Est-ce dû à une mauvaise gestion des rollback segments, ou encore au rownum que j'ai mis dans ma requête mais dont je ne suis pas très sûre qu'il soit très adapté ?
    J'espère que vous pourrez me filer un coup de main et des idées en prime !

  2. #2
    CD
    CD est déconnecté
    Membre éprouvé
    Inscrit en
    Septembre 2004
    Messages
    127
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 127
    Par défaut
    Et en passant par un create as select ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    create table PICKDETAIL_NEW as select * from PICKDETAIL where EXPORTFLAG != 'E';
     
    create PICKDETAIL_OLD as select * from PICKDETAIL;
     
    truncate table PICKDETAIL drop storage;
     
    insert into PICKDETAIL select * from PICKDETAIL_NEW;
     
    commit;

  3. #3
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 19
    Par défaut
    Juste une précision après de nouveaux tests. J'ai lancé la même chose sur une autre table (même ordre de grandeur). Là, pas de problème, le script a bien tourné. Les suppressions ont été correctement faites.
    Je l'ai alors lancé sur une troisième table (pour confirmation ). Et là, j'ai eu une erreur différente de sur la première :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ORA-00600: internal error code, arguments: [4511], [], [], [], [], [], [], []
    ORA-06512: at line 13
    Quel est votre avis ?
    Merci de votre aide

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    376
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 376
    Par défaut
    Redémarre ta base ...
    LEs internal error c'est jamais très bon ...

  5. #5
    CD
    CD est déconnecté
    Membre éprouvé
    Inscrit en
    Septembre 2004
    Messages
    127
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 127
    Par défaut
    Oui, ce n'est jamais très bon.

    Tu as une note sur Metalink concernant ton erreur:
    http://metalink.oracle.com/metalink/...T&p_id=39553.1

  6. #6
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 19
    Par défaut
    Ok, je redémarre ma base puis je teste la méthode de CD qui m'a l'air franchement mieux que la mienne.
    Je vous tiens au courant. Merci.

  7. #7
    CD
    CD est déconnecté
    Membre éprouvé
    Inscrit en
    Septembre 2004
    Messages
    127
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 127
    Par défaut
    Citation Envoyé par CD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    create table PICKDETAIL_NEW as select * from PICKDETAIL where EXPORTFLAG != 'E';
     
    create PICKDETAIL_OLD as select * from PICKDETAIL;
    (...)
    Oupsss... Erreur d'inattention, il faut lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    create table PICKDETAIL_OLD as select * from PICKDETAIL;

  8. #8
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Par défaut
    Personnellement, je choisirais un gros rollback segment comme tu le fais, et pour la suppression je ferais directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    delete from WMSP.PICKDETAIL 
    where         EXPORTFLAG = 'E'

    Laly.
    In the heart of the truly greats, perfection is never achieved but endlessly pursued.

    Mon article sur les fonctions analytiques d'Oracle (calcul de moyennes mobiles, de quartiles et bien d'autres...)

  9. #9
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 25
    Par défaut
    bonjour,
    ce qui serait interessant de savoir dans ton cas est :
    Est-ce un traitement regulier?
    Tu surprimes 10.000 lignes sur combien?

    Ta table a des index et peut etre des stats il faudrait penser à remettre cela d'aplon si ton traitement est regulier.
    A faire trop de delete sur une table on modifie sa HWM.
    Perso sur de la forte volumetrie(>1 M lignes) je prefere recréer la table.
    En dessous de 100.000 j'utilise delete
    A+

  10. #10
    Membre éprouvé
    Inscrit en
    Février 2004
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 97
    Par défaut
    Citation Envoyé par txouki
    A faire trop de delete sur une table on modifie sa HWM.
    Non, c'est justement le probleme, un DELETE ne modifie pas la HWM; seul un TRUNCATE remet la HWM a zero.

  11. #11
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 25
    Par défaut
    Ouais , je me suis mal exprimé(desolé) , delete ne modifie HWM de la table alors que la HWM de la table est modifiée d'ou plantage possible sur explain plan

  12. #12
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 19
    Par défaut
    Je comprends pas bien tout ce que vous me dites alors je préfère vous donner des précisions.
    Dans mon cas, il s'agit là d'un premier archivage sur cette bdd. J'ai donc quelque 100 000 enregistrements sur plusieurs tables. Ensuite, il sera lancé automatiquement une fois par semaine donc je n'aurais plus beaucoup de lignes. Toutefois, je préfère me baser sur ce premier archivage afin d'assurer une certaine pérennité à mon script.
    On a une appli qui est sensé faire cet archivage suite à un dév spécifique qu'on a demandé à notre éditeur. Mais, hélas, c'est une catastrophe parce qu'ils sont pas foutu de bosser correctement.
    Conclusion, j'essaie de m'y coller à partir d'un de leur script et de shunter l'appli en complétant leur propre script.
    Le premier script (celui fourni par l'éditeur) met un flag sur chacune des lignes à archiver en tenant compte des contraintes ... Dans cette partie du script, j'ai également affaire à des analyses régulières des tables modifiées.
    Mon propre script n'a donc plus à s'occuper que de passer les lignes à archiver d'un schéma à un autre en se basant exclusivement sur le flag. Je viens de lancer le script en test en utilisant la méthode de CD adaptée à ma sauce, soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    set transaction use rollback segment RBSPEC;
    insert into ARCHIVE.TMP_PICKDETAIL
    select * from WMSP.PICKDETAIL where EXPORTFLAG <> ‘E’;
    insert into ARCHIVE.PICKDETAIL
    select * from WMSP. PICKDETAIL where EXPORTFLAG = 'E';
    truncate table WMSP.PICKDETAIL drop storage;
    insert into WMSP.PICKDETAIL
    select * from ARCHIVE.TMP_PICKDETAIL;
    truncate table ARCHIVE.TMP_PICKDETAIL;
    commit;
    J'attends de voir les résultats car j'ai ré-importé ma base de test et complètement relancé le script initial avant cette petite partie de code.
    Je vous tiens au courant. Si vous avez un avis à donner sur la question, n'hésitez pas à me le faire connaître. Merci pour tout.

    Au fait, ça veut dire quoi HWM ?
    Et une autre question, outre les analyses, txouki parle de faire quelque chose sur les indexes : peux-tu me dire quoi et comment ?

    Merci.

  13. #13
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967

  14. #14
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 19
    Par défaut
    Merci pour le renseignement.
    Concernant l'évolution de mes tests, j'ai dû mettre un nouveau commit au milieu de mon petit script. Pas très propre mais je ne vois pas comment faire autrement.
    De plus, j'en suis à la ligne finale qui fait un truncate sur ma table mais là, il ne veut pas le faire pour soucis de contrainte. Je voudrais shunter ce point puisque l'intégrité de mes données est prise en compte par l'ensemble de mon script mais pas forcément table par table. Je cherche un moyen d'y arriver.
    A+.

  15. #15
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 25
    Par défaut
    Si j'ai bien tout compris
    1- tu recupres tes lignes d'archive dans ton nv schema

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    insert into ARCHIVE.PICKDETAIL 
    select * from WMSP. PICKDETAIL where EXPORTFLAG = 'E'
    Apres il faut que tu fasse un maj des ligne dans la base prod des tes données archivé
    1-update sur le flag
    cela evite de toucher au indexes sur les autre columne qui de plus possede a priori des contraintes

    2- drop/create suivant la methode CD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    create table PICKDETAIL_NEW as select * from PICKDETAIL where EXPORTFLAG != 'E';
    DROP TABLE PICKDETAIL CASCADE CONSTRAINT
    ALTER TABLE PICKDETAIL_NEW rename to PICKDETAIL
    il te reste plus qu'a remettre les index + les contraintes
    Peut etre un peu lourd pour 10.000 lignes!

  16. #16
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Par défaut
    Félia,


    Et pourquoi tu ne créerais pas des partitions dans ta table. Tu pourrais (si tu es sous 9i) faire une table partitionnée par liste sur la colonne exportflag. Tous les enregistrements avec 'E' serait dans une partition. Quand une ligne pour laquelle le flag est différent de E est mise à E, elle serait déplacé dans la bonne partition...

    Pour supprimer les enregistrements pour lesquels exportflag='E', ca reviendrait juste à faire un truncate au niveau de la partition donc très rapide voire instantané.

    Tu dis que c'est pour de l'archivage ? Tu peux préciser ? Tu entends pas là historisation ?


    Laly.
    In the heart of the truly greats, perfection is never achieved but endlessly pursued.

    Mon article sur les fonctions analytiques d'Oracle (calcul de moyennes mobiles, de quartiles et bien d'autres...)

  17. #17
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 19
    Par défaut
    Bonjour,

    Quelques nouvelles pour mon script : j'ai réussi à pas mal avancer sur le sujet. Je vous montrerai son détail lorsqu'il sera complètement terminé. Et, d'ailleurs, je vous remercie de votre aide qui m'a été très précieuse.

    Mais, il me reste un dernier détail à régler. Je pense que ma question va vous paraître bête mais si je ne la pose pas, je continuerai à chercher pendant des lustres. Je cherche à mettre l'intégralité de mon script dans une procédure stockée. Mais celle-ci ne peut pas être compilée car elle plante à deux endroits (pour l'instant ...) :
    - sur un ALTER ROLLBACK SEGMENT

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      ...
      DBMS_STATS.GATHER_TABLE_STATS('WMSP', 'TRANSFERDETAIL', METHOD_OPT => 'FOR COLUMNS SIZE 2 EXPORTFLAG');
     
      ALTER ROLLBACK SEGMENT "RBSPEC" ONLINE;
      Utl_file.put_line(Fichier, EvolutionFlag||' Ok');
      ...
    - et sur mes truncate
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
      set transaction use rollback segment RBSPEC;
      insert into ARCHIVE.TMP_ORDERDETAIL
        select * from WMSP.ORDERDETAIL where EXPORTFLAG <> 'E';
      insert into ARCHIVE.ORDERDETAIL
        select * from WMSP. ORDERDETAIL where EXPORTFLAG = 'E';
      alter table WMSP.ORDERDETAILXVAS
      disable constraint FK_ORDERDETAILXVAS02;
      truncate table WMSP.ORDERDETAIL drop storage;
      alter table WMSP.ORDERDETAILXVAS
      enable constraint FK_ORDERDETAILXVAS02;
      commit;
    Le message d'erreur est approximativement le même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:
     
       ( ) - + mod not null others <an identifier>
    Du coup, je me demande si le PL/SQL accepte qu'on lui mélange du SQL (sorti des classiques select, insert, update et delete). Quelqu'un peut-il m'aiguiller ? Par quoi dois-je remplacer mes instructuctions ?
    Merci à vous tous, 8)

  18. #18
    Rédacteur

    Inscrit en
    Septembre 2004
    Messages
    626
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 626
    Par défaut
    C'est parce que ces instructions ALTER, TRUNCATE doivent être "encapsulée" (pourquoi ) dans le PL/SQL en utilisant un execute immediate par exemple.


    Laly.
    In the heart of the truly greats, perfection is never achieved but endlessly pursued.

    Mon article sur les fonctions analytiques d'Oracle (calcul de moyennes mobiles, de quartiles et bien d'autres...)

  19. #19
    Membre averti
    Inscrit en
    Mars 2002
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 19
    Par défaut
    Bonjour,

    Je tenais à vous faire part des résultats de mes différents tests (un peu en retard, mais bon !).
    J'ai fait deux versions de mon script : une pour le premier lancement (gros archivage) et un pour un lancement régulier. Voici un extrait de chacun. Ceux-ci fonctionnent et sont maintenant en prod :
    Gros archivage : Je dois impérativement le lancer hors production
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
      set transaction use rollback segment RBSPEC;
      insert into ARCHIVE.TMP_PICKDETAIL
        select * from WMSP.PICKDETAIL where EXPORTFLAG <> 'E';
      insert into ARCHIVE.PICKDETAIL
        select * from WMSP.PICKDETAIL where EXPORTFLAG = 'E';
      execute immediate 'truncate table WMSP.PICKDETAIL drop storage';
      commit;
     
      set transaction use rollback segment RBSPEC;
        insert into WMSP.PICKDETAIL
      select * from ARCHIVE.TMP_PICKDETAIL;
      execute immediate 'truncate table ARCHIVE.TMP_PICKDETAIL drop storage';
      commit;
    Petit archivage : Je peux le lancer pendant que les gens travaillent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      set transaction use rollback segment RBSPEC;
      insert into ARCHIVE.PICKDETAIL
        select * from WMSP.PICKDETAIL where EXPORTFLAG = 'E';
      execute immediate 'delete from WMSP.PICKDETAIL where EXPORTFLAG = ‘’E’’';
      commit;
    Et voilà ! Je remercie tout ceux qui m'ont filé un coup de main !
    A+.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Suppression et Modification d'un enregistrement
    Par loverdev dans le forum VB.NET
    Réponses: 49
    Dernier message: 21/06/2007, 15h01
  2. Réponses: 13
    Dernier message: 08/03/2007, 12h36
  3. Suppression de tables et d'enregistrement
    Par Marmotine dans le forum Access
    Réponses: 3
    Dernier message: 24/11/2006, 11h31
  4. Réponses: 2
    Dernier message: 08/08/2006, 22h17
  5. [MySQL] Sous-requête renvoyant plus d'un enregistrement
    Par altadeos dans le forum Langage SQL
    Réponses: 5
    Dernier message: 20/04/2006, 11h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo