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

SQL Oracle Discussion :

Rafraichissement d'une grande quantité de données


Sujet :

SQL Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 67
    Points : 37
    Points
    37
    Par défaut Rafraichissement d'une grande quantité de données
    Salut à tous.
    Je suis sur la version 11G

    je dipose d'une table contenant des MILLIONS de lignes.

    Les données de la table doivent être màj quotidiennement et au fil de l'eau
    Je recois les données dans une table dont la structure est identique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CNF_tmp (col1, col2, col3)

    Je précise que env 97% des données recus sont identiques

    Voilà ma question :
    Comment remplacer le contenu de la table CNF par celui de CNF_tmp sans interruption de service ?
    et d'une facon intelligeante ?

    je préfère avoir vos avis avant d'implémenter
    1000 mercis

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    De quel type de modifications s'agit-il ?
    Des ajouts, des modifications, des suppressions ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Merci pour ta réponse Alain,

    la clef de la table est (col1, col2, col3)
    à chaque reception de la table CNF_tmp il faudra remplacer littéralement le contenu de CNF par celui de CNF_tmp

    il faudra faire deux opérations :
    1) supprimer les lignes de CNF qui n'y sont plus dans CNF_tmp
    2) ajouter les nouvelles lignes qui sont dans CNF_tmp et pas encore dans CNF

    Merci

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Est-ce que la commande MERGE ne répondrait pas à ton besoin ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Merci,
    La fonction MERGE aurait été une excellente solution si elle permettait de supprimer les lignes de la table dans la quelle je ferai le merge


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    create table CNF (usr number(3), appli varchar2(5), cmp varchar2(5));
    create table CNF_tmp (usr number(3), appli varchar2(5), cmp varchar2(5));
     
    insert into CNF (usr, appli, cmp) values (1, 'APP01', 'PTF01');
    insert into CNF (usr, appli, cmp) values (2, 'APP01', 'PTF01');
    insert into CNF (usr, appli, cmp) values (4, 'APP01', 'PTF08');
    insert into CNF (usr, appli, cmp) values (5, 'APP01', 'PTF05');
     
    insert into CNF_tmp (usr, appli, cmp) values (1, 'APP01', 'PTF01');
    insert into CNF_tmp (usr, appli, cmp) values (2, 'APP01', 'PTF01');
    insert into CNF_tmp (usr, appli, cmp) values (6, 'APP01', 'PTF06');
    insert into CNF_tmp (usr, appli, cmp) values (7, 'APP01', 'PTF01');
    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
     
    select * from CNF;
           USR APPLI CMP 
    ---------- ----- -----
             1 APP01 PTF01 
             2 APP01 PTF01 
             4 APP01 PTF08 
             5 APP01 PTF05 
     
    select * from CNF_tmp;
           USR APPLI CMP 
    ---------- ----- -----
             1 APP01 PTF01 
             2 APP01 PTF01 
             6 APP01 PTF06 
             7 APP01 PTF01
    Je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MERGE INTO CNF CNF
       USING CNF_tmp TMP
       ON (CNF.usr = TMP.usr and CNF.appli = TMP.appli and CNF.cmp = TMP.cmp)
       WHEN NOT MATCHED THEN INSERT (CNF.usr, CNF.appli, CNF.cmp)
         VALUES (TMP.usr, TMP.appli, TMP.cmp);


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    select * from CNF;
     
           USR APPLI CMP 
    ---------- ----- -----
             1 APP01 PTF01 
             2 APP01 PTF01 
             4 APP01 PTF08 
             5 APP01 PTF05 
             6 APP01 PTF06 
             7 APP01 PTF01
    L'idée est de ne pas avoir dans le résultat les lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
           USR APPLI CMP 
    ---------- ----- -----
             4 APP01 PTF08 
             5 APP01 PTF05

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Bonsoir,

    Il y a aussi la possibilité de :
    renommer la table CNF en CNF_OLD
    et CNF_tmp en CNF

    dans ce cas il faut faire un lock sur la table CNF, interrompre les traitements en cours, ensuite procéder au renomage.

    J'aimerai à tout prix éviter de faire un delete sur la table CNF de la différence. Il s'agit de millions de lignes celà peut s'avérer très lent et très gourmand en terme de ressources

    Merci beaucoup pour vos avis et votre aide

  7. #7
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut,

    Mais la différence est de 3%, non ? Ca fait des millions de lignes ?
    La table CNF est-elle modifiée pendant la journée ? Comment est alimentée la table cnf_tmp ? Les tables sont elles indexées ?

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Bonjour,

    c'est la table CNF_tmp qui est alimentée une fois par jour. son contenu doit être déversé dans CNF.

    Oui la table CNF est indexé sur sa clé, qui est col1, col2, col3

    Merci

  9. #9
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par cyclone_yas Voir le message
    ...La fonction MERGE aurait été une excellente solution si elle permettait de supprimer les lignes de la table dans la quelle je ferai le merge
    ...
    Regardez DELETE where_clause dans merge_update_clause

  10. #10
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Par exemple comme ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    merge into cnf a
    using (
      select b.rowid bid, c.rowid cid, usr, appli, cmp
      from cnf b
        natural full outer join cnf_tmp c
      where b.rowid is null or c.rowid is null) d
    on (a.rowid = d.bid)
    when not matched then insert(a.usr, a.appli, a.cmp) values (d.usr, d.appli, d.cmp)
    when matched then update set a.usr = a.usr delete where 1 = 1;

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  11. #11
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Le DELETE dans le MERGE ne fonctionnera pas, tiré du lien vers la doc proposé par mnitu :
    The only rows affected by this clause are those rows in the destination table that are updated by the merge operation.
    ...
    If a row of the destination table meets the DELETE condition but is not included in the join defined by the ON clause, then it is not deleted.
    Ici il faut supprimer les lignes qui ne sont plus présentent dans la table source.
    Il faut donc faire un DELETE WHERE NOT EXISTS puis un MERGE.

  12. #12
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Ici il faut supprimer les lignes qui ne sont plus présentent dans la table source.
    Merci skuatamad, c'est bien ça qu'il dit et donc ça ne marchera pas! En gros il veut que la table CNF_TMP devient CNF.
    Est-ce que ça se fait une seule fois par jour ou N fois ?

  13. #13
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    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
     
    SQL> CREATE TABLE CNF (usr number(3), appli varchar2(5), cmp varchar2(5));
     
    Table created.
     
    Elapsed: 00:00:00.01
    SQL> CREATE TABLE CNF_tmp (usr number(3), appli varchar2(5), cmp varchar2(5));
     
    Table created.
     
    Elapsed: 00:00:00.01
    SQL>
    SQL> INSERT INTO CNF (usr, appli, cmp) VALUES (1, 'APP01', 'PTF01');
     
    1 row created.
     
    Elapsed: 00:00:00.00
    SQL> INSERT INTO CNF (usr, appli, cmp) VALUES (2, 'APP01', 'PTF01');
     
    1 row created.
     
    Elapsed: 00:00:00.00
    SQL> INSERT INTO CNF (usr, appli, cmp) VALUES (4, 'APP01', 'PTF08');
     
    1 row created.
     
    Elapsed: 00:00:00.01
    SQL> INSERT INTO CNF (usr, appli, cmp) VALUES (5, 'APP01', 'PTF05');
     
    1 row created.
     
    Elapsed: 00:00:00.00
    SQL>
    SQL> INSERT INTO CNF_tmp (usr, appli, cmp) VALUES (1, 'APP01', 'PTF01');
     
    1 row created.
     
    Elapsed: 00:00:00.01
    SQL> INSERT INTO CNF_tmp (usr, appli, cmp) VALUES (2, 'APP01', 'PTF01');
     
    1 row created.
     
    Elapsed: 00:00:00.00
    SQL> INSERT INTO CNF_tmp (usr, appli, cmp) VALUES (6, 'APP01', 'PTF06');
     
    1 row created.
     
    Elapsed: 00:00:00.00
    SQL> INSERT INTO CNF_tmp (usr, appli, cmp) VALUES (7, 'APP01', 'PTF01');
     
    1 row created.
     
    Elapsed: 00:00:00.01
    SQL> commit;
     
    Commit complete.
     
    SQL> merge INTO cnf a
      2  USING (
      3    SELECT b.rowid bid, c.rowid cid, usr, appli, cmp
      4    FROM cnf b
      5      NATURAL full OUTER JOIN cnf_tmp c
      6    WHERE b.rowid IS NULL OR c.rowid IS NULL) d
      7  ON (a.rowid = d.bid)
      8  when NOT matched then INSERT(a.usr, a.appli, a.cmp) VALUES (d.usr, d.appli, d.cmp)
      9  when matched then UPDATE SET a.usr = a.usr DELETE WHERE 1 = 1;
     
    4 rows merged.
     
    Elapsed: 00:00:00.04
    SQL> select * from cnf;
     
           USR APPLI CMP
    ---------- ----- -----
             1 APP01 PTF01
             2 APP01 PTF01
             7 APP01 PTF01
             6 APP01 PTF06
    (Avouez que vous ne l'avez pas lue, ma requête...)

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  14. #14
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par pacmann Voir le message
    ...(Avouez que vous ne l'avez pas lue, ma requête...)
    J’avoue tout de suite mais je ne sais pas si ça change grande chose parce que cette solution peut s’avérer moins intéressante sur une table de quelques millions des enregistrements.

  15. #15
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Boh, je suis pas certain que ça soit moins performant...
    Avec la boule de cristal, je dirais que ça doit revenir au même
    La requête merge va constituer le diff avec left outer join union all right outer join, puis faire le merge. Dans delete puis merge, tu fais également deux fois la jointure.

    Du coup, peut être coder en PL un sort-merge manuel en parcourant les deux curseurs en même temps pourrait être meilleur, surtout si les deux tables sont en IOT

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

  16. #16
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Très probablement.
    Mais si je devrais faire cette opération une seule fois par jour je me suis dit que j’envisagerais des autres solutions comme avoir un synonyme qui pourrait pointer sur la « bonne table » de quelle serait disponible ou bien à des autres solutions moins exotiques.

  17. #17
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Citation Envoyé par pacmann Voir le message
    (Avouez que vous ne l'avez pas lue, ma requête...)
    J'avais lu MERGE et DELETE mais pas ce qu'il y avait au milieu

  18. #18
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    1000 mercis à vous tous

    Effectivement, ne pouvant pas créer d'objet PL, la solution de Pacmann est bonne, la proposition de Mnitu est à étudier aussi.

    Encore une fois Merci

  19. #19
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Attention, la requête telle qu'elle n'est pas correcte si les champs sont nullables. (Planqué dans le natural, les conditions de jointure NULL = NULL ne matchent pas). Il faut dans ce cas préciser les conditions de jointure dans une clause ON en y traitant les cas de double nullité.

    Je me suis fait piéger hier comme un bleu, j'en ai fait un article du coup
    http://pacmann.over-blog.com/article...119128763.html

    @skuat : c'est même pas en diagonal, ça

    (c'est ma photo)
    Paku, Paku !
    Pour les jeunes incultes : non, je ne suis pas un pokémon...

    Le pacblog : http://pacmann.over-blog.com/

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

Discussions similaires

  1. Envoyer une grande quantité de données dans un xml via http
    Par qdaemon_fr dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 03/03/2009, 09h51
  2. Manipulation d'une grande quantité de données
    Par sebastyen dans le forum Langage
    Réponses: 1
    Dernier message: 10/11/2008, 15h54
  3. Réponses: 11
    Dernier message: 23/09/2008, 15h39
  4. Une grande quantité de données sur Oracle 8i?
    Par bliml dans le forum Oracle
    Réponses: 13
    Dernier message: 01/03/2007, 11h45
  5. Réponses: 1
    Dernier message: 10/01/2007, 15h52

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