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 :

Optimisation DELETE


Sujet :

Oracle

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Optimisation DELETE
    Oracle Server 9.2
    Je souhaite effectuer un DELETE important sur une BDD en production au sein d'une table contenant près de 20 millions d'enregistrements.
    Le problème est que cette opération prend un temps extrêmement important et conduit à l'écroulement des performances de la BDD pour les utilisateurs.
    Nous avons essayer d'effectuer l'opération en supprimant temporairement les contraintes sur la table concernée mais cela n'a rien changé.
    La base est en mode NOARCHIVELOG.
    Quelqu'un aurait-il une idée pour améliorer le temps d'exécution de la requête?
    Merci

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    combien de lignes supprimes-tu dans les 20 Millions ?

    Un méthode interessante est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE tab_new
    AS SELECT * FROM tab_a_supprimer
    WHERE <conditions de sauvegarde>;
     
    RENAME TABLE tab_a_supprimer TO tab_sav;
     
    RENAME TABLE tab_new TO  tab_a_supprimer;
     
    recréation des contraintes, triggers, indexes et grant
     
    DROP TABLE tab_sav; -- quand tout est OK
    Si tu ne peux pas te passer de la table même temporairement où que c'est trop contraignant, alors tu peux également supprimer les indexes et triggers avant de supprimer les lignes.

  3. #3
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut
    Si tu ne peux pas appliquer la solution de Fred_D (tout le monde ne peux pas créer deux tables de 20 millions de lignes) et que tu veux que l'on t'aide, tu devrais:
    - nous donner des informations sur la table que tu veux supprimer (colonnes, clés, index, triggers, partitions,...)
    - nous donner des infos sur ton DELETE (requete précise, plan d'exécution, temps d'éxécution,...)

    A bon entendeur
    Dyvim

  4. #4
    Membre éprouvé Avatar de Mathusalem
    Profil pro
    IT moa
    Inscrit en
    Décembre 2003
    Messages
    1 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : IT moa

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 008
    Points : 1 067
    Points
    1 067
    Par défaut
    est ce que la méthode de fred_d est vraiment intéressante, si on doit supprimer moins de 50% de la table ?

    j'ai en effet le même soucis avec une table, ou je dois retirer de temps à autre 3 millions de tuples sur un peu plus de 9.

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    là, il n'y a pas d'autres solutions que tester la méthode... je ne vois pas comment savoir si c'est mieux ou pire qu'un DELETE sans le vérifier

    Parce que pour optimiser un DELETE, je ne vois qu'un autre moyen, c'est de supprimer les indexes avant et les recréer ensuite.

    Donc :
    1°) méthode :
    - insert volume - 3 millions de ligne et create index

    2°) méthode
    - delete 3 millions de ligne et create index

    sachant que la 1° méthode ne consomme pas d'UNDO... donc plus de volume mais pas d'UNDO contre moindre volume avec UNDO... faut voir.

    Peut-on me confirmer par ailleurs que l'INSERT n'utilise pas le UNDO... parce que j'en suis pas certain

  6. #6
    Membre éprouvé Avatar de Mathusalem
    Profil pro
    IT moa
    Inscrit en
    Décembre 2003
    Messages
    1 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : IT moa

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 008
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par Fred_D
    [...] Parce que pour optimiser un DELETE, je ne vois qu'un autre moyen, c'est de supprimer les indexes avant et les recréer ensuite.
    [...]
    En quoi le fait de retirer les indexes peut accélérer un DELETE ?

    De plus, je peux me tromper, mais il me semble que Oracle crée automatiquement un index sur les clés primaires, non ?

    Ce qui voudrait dire qu'il faudrait aussi faire sauter la clé ?

  7. #7
    Membre averti Avatar de macben
    Inscrit en
    Mars 2004
    Messages
    546
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2004
    Messages : 546
    Points : 433
    Points
    433
    Par défaut
    Citation Envoyé par Mathusalem
    En quoi le fait de retirer les indexes peut accélérer un DELETE ?
    Moi c'est plus pour ma culture perso, mais en quoi le fait de retirer LES triggers peut accélérer un Delete ? De quel triggers parles-tu ? Les triggers genre ON INSERT, ON UPDATE, ON DELETE, ou d'autres (donc je ne connaitrais pas l'existence) ?

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    les triggers ON DELETE bien entendu

    Il faut supprimer les indexes pour éviter de perdre du temps à les mettre à jour pendant le traitement de suppression. Il peut être plus avantageux de le recréer

  9. #9
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut
    Citation Envoyé par Mathusalem
    En quoi le fait de retirer les indexes peut accélérer un DELETE ?

    De plus, je peux me tromper, mais il me semble que Oracle crée automatiquement un index sur les clés primaires, non ?

    Ce qui voudrait dire qu'il faudrait aussi faire sauter la clé ?

    Un trigger on DELETE sera joué chaque fois que tu supprimera des lignes donc si tu désactive le TRIGGER tu accélère le process puisque cela fait du code en moins à éxécuter.
    De la même façon si tu supprimes les clés et les contraintes tu gagnes du temps.
    Pour les index tu gagnes le temps nécessaire pour les mettre à jour.

    Concernant les index de clef primaire, tu peux les supprimer sans supprimer la clé.
    Dyvim

  10. #10
    Membre averti Avatar de macben
    Inscrit en
    Mars 2004
    Messages
    546
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2004
    Messages : 546
    Points : 433
    Points
    433
    Par défaut
    Citation Envoyé par Fred_D
    les triggers ON DELETE bien entendu
    Ah ok... moi je trouve ça dommage de supprimer ON DELETE au moment de faire un ... DELETE

    (Ok j'ai compris que c'est dans le cas où le ON DELETE ne doit s'appliquer que pour un DELETE "non-purge" mais un DELETE applicatif).

  11. #11
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut
    Attention, si tu désactive les contraintes, triggers,... tu t'expose à des problèmes d'intégrité.

    Assure toi que tu seras le seul à utiliser la table à ce moment là...

    Peut être que tu peux le faire en une seule transaction spécifiée dans un bloc PL, mais je me demandes ce qu'il advient des ordres en EXECUTE IMMEDIATE.
    Dyvim

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Tout d'abord, merci à tous pour vos réponses.

    Pour répondre aux diverses questions:
    - l'objectif dans un premier temps est de purger près de 80% de la table... puis de la purger régulièrement au fur et à mesure de son incrémentation.

    - ta solution fred peut être envisageable mais elle est effectivement contraignante : la base est rattachée à un progiciel pour lequel nous avons un support, mais malheureusement trop incompétent pour nous fournir une solution appropriée à notre problème. Et toucher à la structure de la base est par conséquent un peu délicat. m'enfin si on a pas le choix...

    - la structure de la table est la suivante :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
     
    CREATE TABLE "ODB"."" ("AC" VARCHAR2(10 byte) NOT NULL, 
        "FLIGHT_LOG" VARCHAR2(12 byte) NOT NULL, "FLIGHT_LEG" 
        NUMBER(4) NOT NULL, "FLIGHT_DATE" DATE, "ORIGIN" VARCHAR2(4 
        byte), "DESTINATION" VARCHAR2(4 byte), "FLIGHT" VARCHAR2(10 
        byte), "STATUS" VARCHAR2(10 byte), "OFF_HOUR" NUMBER(2), 
        "OFF_MINUTE" NUMBER(2), "TO_HOUR" NUMBER(2), "TO_MINUTE" 
        NUMBER(2), "LDG_HOUR" NUMBER(2), "LDG_MINUTE" NUMBER(2), 
        "ON_HOUR" NUMBER(2), "ON_MINUTE" NUMBER(2), "FLIGHT_HOURS" 
        NUMBER(6), "FLIGHT_MINUTES" NUMBER(2), "CYCLES" NUMBER(6), 
        "BLOCK_HOURS" NUMBER(6), "BLOCK_MINUTES" NUMBER(2), 
        "TOTAL_AC_FLIGHT_HOURS" NUMBER(6), "TOTAL_AC_FLIGHT_MINUTES" 
        NUMBER(2), "TOTAL_AC_CYCLES" NUMBER(6), 
        "TOTAL_AC_BRAKE_CYCLES" NUMBER(6), "TOTAL_AC_BLOCK_HOURS" 
        NUMBER(6), "TOTAL_AC_BLOCK_MINUTES" NUMBER(2), 
        "FLIGHT_CATEGORY" VARCHAR2(8 byte), "FUEL_BURNED" NUMBER(5), 
        "NOTES" NUMBER(8), "CREATED_BY" VARCHAR2(10 byte), 
        "CREATED_DATE" DATE NOT NULL, "MODIFIED_BY" VARCHAR2(10 byte),
        "MODIFIED_DATE" DATE NOT NULL, "VOID" VARCHAR2(10 byte), 
        "PILOT_FLIGHT_HOURS" NUMBER(6), "PILOT_FLIGHT_MINUTES" 
        NUMBER(2), "UPDATE_MODE" VARCHAR2(10 byte), "BLOB_NO" 
        NUMBER(8), "ETOPS_FLIGHT" VARCHAR2(10 byte), 
        "AC_MAINTENANCE_RESET" VARCHAR2(10 byte), "PILOT_CYCLES" 
        NUMBER(6), "CAT_RATING" VARCHAR2(10 byte), "MAINTENANCE_LOG" 
        VARCHAR2(10 byte), "FLIGHT_HOURS_AT_CLOSING" NUMBER(6), 
        "FLIGHT_MINUTES_AT_CLOSING" NUMBER(2), "CYCLES_AT_CLOSING" 
        NUMBER(6), "CAT_TYPE" VARCHAR2(2 byte), "CAT_RESULT" 
        VARCHAR2(2 byte), 
        CONSTRAINT "FK_AC_ACTUAL_FLIGHT_AUDIT_1" FOREIGN KEY("AC") 
        REFERENCES "ODB"."AC_MASTER"("AC") 
        ON DELETE CASCADE, 
        CONSTRAINT "P_AC_ACTUAL_FLIGHTS_AUDIT_1" PRIMARY KEY("AC", 
        "FLIGHT_LOG", "FLIGHT_LEG", "CREATED_DATE", "MODIFIED_DATE") 
        USING INDEX  
        TABLESPACE "USR" 
        STORAGE ( INITIAL 1215712K NEXT 0K MINEXTENTS 1 MAXEXTENTS 
        2147483645 PCTINCREASE 0) PCTFREE 10 INITRANS 2 MAXTRANS 255)
     
        TABLESPACE "USR" PCTFREE 10 PCTUSED 0 INITRANS 1 MAXTRANS 255
        STORAGE ( INITIAL 2097152K NEXT 0K MINEXTENTS 1 MAXEXTENTS 
        2147483645 PCTINCREASE 0) 
        LOGGING
    et d'ailleurs je viens de me rendre compte qu'il y a un trigger sur DELETE... que signifie CASCADE?

    - le DELETE est très simple : le but est de purger les enregistrements antérieurs à une date donnée (champ FLIGHT_DATE). cela donne quelque chose du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DELETE FROM ODB.AC_ACTUAL_FLIGHTS_AUDIT
    WHERE FLIGHT_DATE<='01-FEB-03'
    J'avais essayer de "décomposer" la suppression, en lançant une requête quotidienne la nuit du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    DELETE FROM(
    SELECT ROWID FROM
    (SELECT *
    FROM ODB.AC_ACTUAL_FLIGHTS_AUDIT
    ORDER BY FLIGHT_DATE)
    WHERE ROWNUM<1000);
    qui devrait me permettre de purger petit à petit la table sans m'en préoccuper, mais le problème est que ROWNUM ne semble pas fonctionner avec DELETE : les enregistrement supprimés ne correspondent pas aux plus petits ROWNUM, cad aux dates les plus petites. Comprend pas..

  13. #13
    Membre éprouvé Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Points : 931
    Points
    931
    Par défaut
    et que donne juste un Select avec la même clause que le Delete ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Select * from Actual_Flight_Audit
    WHERE FLIGHT_DATE<='01-FEB-03'
    au niveau du plan d'execution ? est-ce que ça passe par un index ?

    mon but est de savoir si la perte de temps provient de la selection des rows à effacer ou du delete lui-même...
    Il est plus facile de voir les signes avant-coureurs après coup que l'inverse !

    Yorglaa

  14. #14
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut
    Est ce qu'il ne s'agirait pas de purger un mois entier par exemple?

    Parce que dans ce cas là une table partitionnée avec des DELETE qui mentionnent les partitions (voire même des suppressions de partitions entières) te permettrait de gagner du temps.
    Il faut partitionner par valeur (BY RANGE) en définissant des valeurs délimitants les partitions.

    Sinon une bonne question est : as tu un index sur ta colonne FLIGHT_DATE?
    Dyvim

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    27
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Canada

    Informations forums :
    Inscription : Février 2004
    Messages : 27
    Points : 35
    Points
    35
    Par défaut
    Pour épurer des données dans le temps comme dans un entrepôts de données. Je partionne mes tables de faits, donc j'ajoute une nouvelle partition a chaque mois et je supprime toujours le plus vieux mois ce qui fait que j'ai toujours 13 mois d'historique. De plus la suppression d'une partition est très rapide (environ 3 secondes pour 8 millions d'enregistrements), mais ne permet pas au Triggrer de ON DELETE d'effectuer leur travail.

    Research

  16. #16
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2005
    Messages
    250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 250
    Points : 277
    Points
    277
    Par défaut
    Citation Envoyé par poups
    et d'ailleurs je viens de me rendre compte qu'il y a un trigger sur DELETE... que signifie CASCADE?
    Il ne s'agit pas d'un TRIGGER mais d'une contrainte d'intégrité(à moins que tu ais un TRIGGER mais tu ne l'as pas montré).
    Visiblement tu références une autre table via cette clef étrangère:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CONSTRAINT "FK_AC_ACTUAL_FLIGHT_AUDIT_1" FOREIGN KEY("AC") REFERENCES "ODB"."AC_MASTER"("AC") ON DELETE CASCADE,
    le terme CASCADE signifie que lorsque tu supprime des lignes sur la table mère, les lignes de la table fille sont supprimées aussi.
    Dyvim

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 34
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Research Am
    Pour épurer des données dans le temps comme dans un entrepôts de données. Je partionne mes tables de faits, donc j'ajoute une nouvelle partition a chaque mois et je supprime toujours le plus vieux mois ce qui fait que j'ai toujours 13 mois d'historique. De plus la suppression d'une partition est très rapide (environ 3 secondes pour 8 millions d'enregistrements), mais ne permet pas au Triggrer de ON DELETE d'effectuer leur travail.

    Research
    Salut Research Am, pourrait tu m'en dire s'il te plait ? je suis dans un cas de suppression d'un grand nombre d'enregistrement dans uen base datamart, et j'ai environ 26 millions d'enregistrements à purger,
    donc si je savais comment faire une partition et comment supprimer les enregistrements associés à cette partition, ça serait génial !!

    Merci d'avance :=)

  18. #18
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    j'ai effectué l'essai sur les contraintes en test : j'ai desactiver les contraintes sur les clés primaire et étrangère avec Oracle Manager, ça a également fait disparaitre l'index. Et le résultat est excellent, le temps d'exécution du DELETE est quasiment divisé par 10! Je ferai un essai partiel en prod demain pour voir l'impact sur l'utilisation de la base.
    L'utilisation du NOLOGGING semble également permettre une amélioration sensible.
    Merci à tous pour votre aide précieuse

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    en effet, NOLOGGING permet de limiter les écritures dans les redos

  20. #20
    Membre averti Avatar de Wurlitzer
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 469
    Points : 408
    Points
    408
    Par défaut
    NOLOGGING ?? Je croyais que cela ne fonctionnait que pour des Inserts. Quelqu'un a t il un doc. Pour confirmer ou infirmer cette idée.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Optimisation] Delete beaucoup plus lent que select
    Par GyZmoO dans le forum Requêtes
    Réponses: 17
    Dernier message: 18/07/2017, 19h08
  2. Optimisation delete in
    Par nicotine dans le forum SQL
    Réponses: 6
    Dernier message: 14/06/2011, 11h41
  3. optimisation delete requete
    Par ekremyilmaz dans le forum Langage SQL
    Réponses: 1
    Dernier message: 19/04/2010, 10h52
  4. Optimiser delete sur table
    Par fulub dans le forum Administration
    Réponses: 13
    Dernier message: 16/06/2009, 22h05
  5. Optimisation de DELETE
    Par RitonLaBevue dans le forum Requêtes
    Réponses: 5
    Dernier message: 02/11/2005, 15h31

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