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 :

[tuning]Maj d'une forte volumétrie


Sujet :

Oracle

  1. #1
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 24
    Points : 22
    Points
    22
    Par défaut [tuning]Maj d'une forte volumétrie
    Salut tous,
    Je travaille actuellement sur la création d'une grose base de données (40 TO de données).

    Mon datawarehouse est sous oracle et j'effectue des mises à jour mensuelles.
    Pour faire les mises à jour, je me suis rendu compte que l'uptdate est excrécable en terme de performance,
    du coup j'utilises les "ordres"
    Delete from

    Insert


    Ma volumétrie augmentant fortement, je viens de mettre à jour 1 table de 20 millions de lignes en 3h...

    Je voulais savoir si il y a un moyen en auracle de réduire fortement le temps de traitmeent pour les mises à jour ...

    Merci d'avance

  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 : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    très mauvaise idée, il n'y a rien de pire qu'un DELETE

    Commençons par le commencement : version d'Oracle ? Partitioning installé (et license payée ) ? Volume de la table en question, FK, index, etc...

    Dis nous tout

  3. #3
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 24
    Points : 22
    Points
    22
    Par défaut
    Alors :

    Oracle 9;
    Partionning activé par rapport à un code_date;
    Volume de la table : 20 Millions de lignes soit ~20 Go (bcp de colonnes... )
    Ouais la table est indexée, et y a 3 FK

    Comment faire le update, car effectivement le delete est tout pourri,
    mais le update
    est pire !!
    Merci de ton/votre aide

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Citation Envoyé par Fred_D
    très mauvaise idée, il n'y a rien de pire qu'un DELETE
    Tu veux dire à cause de la HWM, par opposition à TRUNCATE ?

  5. #5
    Rédacteur

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 320
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 320
    Points : 3 798
    Points
    3 798
    Par défaut
    Citation Envoyé par Magnus
    Tu veux dire à cause de la HWM, par opposition à TRUNCATE ?
    et également par rapport à la gestion des UNDO/RBS

  6. #6
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 24
    Points : 22
    Points
    22
    Par défaut
    S'il vous plait
    parlez en français,
    ou expliquez un minimum,
    suis junior en oracle !
    Merci

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    la High Water Mark est un marqueur qui permet à Oracle de savoir où est le dernier bloc du tablespace. Le problème c'est qu'il est remis à 0 que lors de la création de la table ou d'un TRUNCATE (sans REUSE STORAGE). Du coup, tu peux très bien avoir un COUNT(*) qui dure très longtemps pour retourner 0... c'est parce qu'Oracle parcourt tous les blocs en cas de FULL SCAN.

    Trève de digression , le DELETE consomme du UNDO et du REDO, ce que fait aussi l'INSERT... du coup, ça fait double consommation. Si l'update est long c'est peut-être à cause des FK et/ou de trigger. Est-ce que l'update est sur la clé de partitionnement ? Est-ce qu'il est sur des FK ? Est-ce qu'il utilise bien les indexes ?

  8. #8
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 24
    Points : 22
    Points
    22
    Par défaut
    le delete/insert porte seulement sur les indexes (ni FK, ni clefs de partitionnement)...
    C'est mal docteur ??

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    faudrait voir l'ordre de mise à jour (et le plan d'exécution) ainsi que le script de création de l'update

  10. #10
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 24
    Points : 22
    Points
    22
    Par défaut
    En fait nous avons intégré des procédures génériques pour toutes les tables du DWH,
    ceci dit la technique 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
     
                                execute(
                                        alter session enable parallel dml
                                       ) by oracle;
     
                                execute(
                                        delete &cible
                                        from &table_cible
                                        parallel
                                        where %nomchampp(champ=nompk, n=&nbpk) in (select &source %nomchampp(champ=nompk, n=&nbpk)
    from &table_source)
                                       ) by oracle;
     
                                execute(
                                        commit
                                       ) by oracle;
     
                                execute(
                                        insert &cible into &table_cible
                                        select &source *
                                        from &table_source
                                       ) by oracle;
     
                               execute(
                                        commit
                                       ) by oracle;
     
                                execute(
                                        drop table &table_source
                                       ) by oracle;
                           disconnect from oracle;

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    non mais c'est pas l'UPDATE ça

    C'est quoi ces EXECUTE ??? C'est du PRO*C ?

  12. #12
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 24
    Points : 22
    Points
    22
    Par défaut
    C'est du SAS...
    Le 'execute' permet de se connecter directement à la base oracle et de passer des instructions SQL.
    Effectivement ce n'est pas de l'update comme je l'ai dit dans le 1er message
    mais du

    Delete
    Insert

    ce qui est équivalent, sauf que les performances sont un peu meilleures...
    Vois tu un autre moyen de réaliser ces opérations ?
    Merci

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Non mais justement, j'aimerais bien qu'on en revienne à l'update qui sera probablement la meilleure manière d'améliorer le process

  14. #14
    Membre expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Points : 3 597
    Points
    3 597
    Par défaut
    Une des solutions possibles au problème de la mise à jour massive est de réaliser la mise à jour avec un CREATE TABLE AS SELECT si on peut coder la mise à jour dans le SELECT (avec l'inconvénient de devoir recréer les indexes, les contraintes et les droits ...):

    Voir http://asktom.oracle.com/pls/ask/f?p...:6407993912330

    Mais il y a probablement d'autres solutions avec le partionnement ?

  15. #15
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Après plusieurs tests nous avons trouvé cette solution pour notre DWH

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    SQL>DROP TABLE my_command;
     
    Table supprimée.
     
    Ecoulé : 00 :00 :00.00
    SQL>
    SQL>CREATE TABLE my_command
      2        (artno number(10), cmddate date)
      3    PARTITION BY RANGE (cmddate)
      4        (PARTITION an_1999 VALUES LESS THAN (TO_DATE('01/01/2000','DD/MM/YYYY'))
      5            TABLESPACE tbs1999,
      6         PARTITION an_2000 VALUES LESS THAN (TO_DATE('01/01/2001','DD/MM/YYYY'))
      7            TABLESPACE tbs2000);
     
    Table créée.
     
    Ecoulé : 00 :00 :00.00
    SQL>    
    SQL>insert into my_command values(1,TO_DATE('01/01/2000','DD/MM/YYYY'));
     
    1 ligne créée.
     
    Ecoulé : 00 :00 :00.00
    SQL>insert into my_command values(2,TO_DATE('01/01/1999','DD/MM/YYYY'));
     
    1 ligne créée.
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command ;
     
         ARTNO CMDDATE
    ---------- --------
             2 01/01/99
             1 01/01/00
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command partition (an_1999);
     
         ARTNO CMDDATE
    ---------- --------
             2 01/01/99
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command partition (an_2000);
     
         ARTNO CMDDATE
    ---------- --------
             1 01/01/00
     
    Ecoulé : 00 :00 :00.00
    SQL>ALTER TABLE my_command TRUNCATE PARTITION an_2000;
     
    Table tronquée.
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command ;
     
         ARTNO CMDDATE
    ---------- --------
             2 01/01/99
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command partition (an_1999);
     
         ARTNO CMDDATE
    ---------- --------
             2 01/01/99
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command partition (an_2000);
     
    aucune ligne sélectionnée
     
    Ecoulé : 00 :00 :00.00
    SQL>ALTER TABLE my_command TRUNCATE PARTITION an_1999;
     
    Table tronquée.
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command ;
     
    aucune ligne sélectionnée
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command partition (an_1999);
     
    aucune ligne sélectionnée
     
    Ecoulé : 00 :00 :00.00
    SQL>select * from my_command partition (an_2000);     
     
    aucune ligne sélectionnée
     
    Ecoulé : 00 :00 :00.00
    SQL>
    Utilisation des partitions + truncate + insert (pourquoi pas directement dans une partition !!)

    Bref bien découpé les partitions (en fonction du plus gros volume traité et sa fréquence !)

    On peut aussi faire des sous partition genre Année/Mois mais je sais pas si les truncate fonctionne pour une sous partition à voir.

    Bon courage

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

Discussions similaires

  1. Comment optimiser une alerte mail à fort volume
    Par El Riiico dans le forum SQL Procédural
    Réponses: 7
    Dernier message: 02/02/2007, 11h33
  2. Maj d'une base 7.0 vers une base 2000
    Par ditter dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 23/11/2005, 18h05
  3. Problème de MAJ d'une zone de liste
    Par Jérémy VAUTIER dans le forum Access
    Réponses: 3
    Dernier message: 17/10/2005, 15h09
  4. Erreur de maj d'une table !
    Par smail21 dans le forum Bases de données
    Réponses: 6
    Dernier message: 30/08/2005, 16h18
  5. MAJ d'une table sous SQL Server par insertion
    Par keish dans le forum Langage SQL
    Réponses: 6
    Dernier message: 11/06/2003, 17h23

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