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 :

Copie partielle d'une grosse table pour conserver un historique


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Copie partielle d'une grosse table pour conserver un historique
    le but : créer une table d'historique AH à partir de la table A qui contient plus de 20 millions de lignes ainsi qu'une bonne poignée d'indexes mal foutues (mais ça c'est une autre histoire, malheureusement). Ensuite suppression dans la table source des enregistrements historisés pour arrive à une taille de 3 millions de lignes.
    J'aimerais bien sûr que ça prennent le moins de temps possible en essayant de garder la bd et la table A accessible.

    Voici ce que j'ai l'intention de faire :

    • Désactivation des contraintes de la table A
    • Drop des indexes sur la table A sauf celui sur la clef primaire A_ID et sur la champ date : A_date
    • CREATE table AH AS select * from A where A_date < to_date('01/01/2007','DD/MM/YYYY');
    • delete A where A_Date < to_date('01/01/2007','DD/MM/YYYY');
    • recréation des indexes
    • réactivation des contraintes


    Je serais bien passé par DataPump pour sauvegarder ma table A puis recréer un table AH identique mais je n'ai pas trouver de possibilité de faire un remap_tables, malheureusement...

    Si vous avez des propositions plus intelligentes ou des optimisations à apporter, n'hésitez pas.

    [EDIT]JE SUIS EN 10G...
    Dernière modification par Invité ; 23/04/2008 à 18h13.

  2. #2
    Membre émérite Avatar de philcero
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Septembre 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2007
    Messages : 528
    Par défaut
    De mon point de vue :
    • As-tu un index sur la colonne A_Date afin d'accélérer le mouvement.
    • Je ne ferrais pas de DROP INDEX car si pendant l'indisponibilité des indexs tu as deux ou trois clients qui ont l'intelligence suprême d'interroger ta table A avec des croisements sur B ou C, bonjour l'explosion de CPU et de temps perdu. Je me contenterais d'un ALTER INDEX REBUILD (Sans oublier le recalcul des statistiques pour tout le monde).
    • As-tu la possibilité de positionner ta table historique dans un tablespace situé sur des disques physiques séparés de ta table principale.
    • Tu peux également lancer un script de création seulement de ta table historique pendant la nuit où il n'y a personne. Suivi d'une recherche pour être un peu parano : select * from A where A_date < to_date('01/01/2007','DD/MM/YYYY') and A.XXX not in (select xxx from AH); (Où xxx est une colonne/clef primaire). As toi de faire juste les DELETE, ALTER INDEX REBUILD & COMPUTE STATISTICS le lendemain soir (Avoir deux passes avec un doublage des données pendant une journée ne me choque pas).

  3. #3
    Membre éclairé Avatar de lmartin
    Inscrit en
    Avril 2008
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 61
    Par défaut
    Une première solution :

    1) Tu split ta table en deux partitions par rapport à ta date.
    2) Tu fais un exchange partition entre ta partition de données Historique et ta table AH.
    3) Tu drop ta partition de données Historique
    4) Tu (re)calcules tes stats, bien sûr

    Le problème est alors de conserver ou non les "historiques" dans ta table H

    Si oui il faudrait plutot faire un truc comme ça :
    0) Tu créé une table AH partitionné RANGE sur les date
    1) Tu ajoute une partition à ta table AH en fonction de ta nouvelle date à historiser
    2) Tu split ta table Opérationnelle en deux partitions par rapport à ta date.
    3) Tu fais un exchange partition entre ta partition de données Historique et une table TEMPORAIRE.
    4) Tu refais un exchange partition en TEMP et nouvelle partition AH
    5) Tu drop ta partition de données Historique dans la table opérationnelle
    6) Tu (re)calcules tes stats

    C'était une idée ...

  4. #4
    Invité
    Invité(e)
    Par défaut
    • As-tu un index sur la colonne A_Date afin d'accélérer le mouvement.
    • Je ne ferrais pas de DROP INDEX car si pendant l'indisponibilité des indexs tu as deux ou trois clients qui ont l'intelligence suprême d'interroger ta table A avec des croisements sur B ou C, bonjour l'explosion de CPU et de temps perdu. Je me contenterais d'un ALTER INDEX REBUILD (Sans oublier le recalcul des statistiques pour tout le monde).

      En réponse aux deux questions précédentes, j'ai bien un index sur la clef primaire et un autre sur la date que je garde actif.

      Je pense que la manipulation se fera avec les applications déconnectées de la base, on va les basculer sur la base de standby, autant en profiter.,

      Le pourquoi je supprime les autres indexes, c'est qu'ils me semblent loin d'être pertinent (historique de la bd datant de la 8i) et qu'il ralentisse considérablement la manoeuvre de copie.
      exemples :
      CREATE INDEX A_I04 ON A (TO_NUMBER(TO_CHAR(A_DATE,'YYYYMMDD'))) ;
      CREATE INDEX A_I05 ON A (TO_NUMBER(TO_CHAR(A_DATE,'YYYYMMDDHH24MISS')))
      Oui, ça fait hurler, hein !
      D'autant plus que dans l'application, il y a des select qui font des TO_NUMBER(TO_CHAR(A_DATE,'YYYYMMDDHH24MISS')) + Variable...
      Je me demande bien comment ça fait pour marcher...
      Mais bon, depuis le temps que ça tourne, ça doit pas trop mal fonctionner tout de même...
      Il est prévu de réviser cette application, ouf !


    • As-tu la possibilité de positionner ta table historique dans un tablespace situé sur des disques physiques séparés de ta table principale.

      Non, je ne pense pas que celà soit possible. Je me renseigne.

    • Tu peux également lancer un script de création seulement de ta table historique pendant la nuit où il n'y a personne. Suivi d'une recherche pour être un peu parano : select * from A where A_date < to_date('01/01/2007','DD/MM/YYYY') and A.XXX not in (select xxx from AH); (Où xxx est une colonne/clef primaire). As toi de faire juste les DELETE, ALTER INDEX REBUILD & COMPUTE STATISTICS le lendemain soir (Avoir deux passes avec un doublage des données pendant une journée ne me choque pas).


      Question, est-il plus rapide de faire une copie entière de la table
      create table AH as select * from A
      puis
      delete AH where AH_Date < to_date('01/01/2007','DD/MM/YYYY');

      que de faire directement :
      CREATE table AH AS select * from A where A_date < to_date('01/01/2007','DD/MM/YYYY');


    Et je m'informe sur le partitionnement de ma table...

  5. #5
    Membre éclairé Avatar de lmartin
    Inscrit en
    Avril 2008
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 61
    Par défaut
    Il est clairement plus rapide de faire un CREATE AS SELECT qu'une Copie puis DELETE.

    Selon le nombre de lignes il peut être plus rapide de faire :
    CREATE TABLE AH
    puis INSERT /*+ append */ sur AH depuis A

    Pour le partitionnement il faut avoir payé une licence en plus pour cette fonctionnalité.

  6. #6
    Membre émérite Avatar de philcero
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Septembre 2007
    Messages
    528
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2007
    Messages : 528
    Par défaut
    Le partitionnement est effectivement une bonne idée, même si celui-ci est situé sur les même volumes physiques il devrait se solder par un gel de l'utilisation de certaines zones des disques d'où une diminution de la ballade des têtes de lecture dans le seul cas où les blocs impactés sont soit à l'intérieur, soit à l'extérieur de la répartition des disques. C'est pourquoi on ne partitionne sur un même espace physique qu'avec l'aide d'un gestionnaire de volumes logiques qui permettra de définir des politiques de placement de ceux-ci.

    Je pense que la manipulation se fera avec les applications déconnectées de la base, on va les basculer sur la base de standby, autant en profiter.,
    Si je comprends bien tu vas envoyer tout le monde sur ton autre serveur, stopper l'application des archives et une fois la manipulation terminée rapatrier les gens en local ?

    Et tu fais comment pour ramener les m.a.j de ta base standby vers ta base primaire ?

    Mis à part la supprimer et la recréer à partir de ta standby et perdre tout ton boulot je voie pas...


  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par philcero Voir le message
    Si je comprends bien tu vas envoyer tout le monde sur ton autre serveur, stopper l'application des archives et une fois la manipulation terminée rapatrier les gens en local ?

    Et tu fais comment pour ramener les m.a.j de ta base standby vers ta base primaire ?

    Mis à part la supprimer et la recréer à partir de ta standby et perdre tout ton boulot je vois pas...
    En fait, je m'aperçois que je ne donne pas toutes les infos.
    La base standby va prendre le relais pendant la manip mais elle est en lecture seule donc, les utilisateurs ont accès aux infos mais ne peuvent pas les modifier (et c'est ok pour ce client) donc les bds restent synchro.

    J'ai trouvé un contournement bête mais temporaire à mon problème : en fait, dans les requêtes de l'application, il y a des hints qui foutent la grouille. J'ai simplement renommé les indexes et du coup, l'optimiseur fait son travail correctement puisqu'il ne trouve plus les indexes indiqués (une requête bloquante est passée de 2 min 30 à 3 secondes ).
    Mais il va falloir optimisé cette appli, parce que les
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    where to_number(to_char (colonne,'YYYYMMDD')) between to_number(to_char (PAR1,'YYYYMMDD')) - PAR2 and to_number(to_char (PAR1,'YYYYMMDD')) + PAR2
    j'ai vu mieux...
    Et pour la création de la table d'historisation, vu qu'il n'y a plus d'urgence, je vais faire ça en plusieurs fois par petits bouts.

    Merci de votre aide à tous.

Discussions similaires

  1. Copie partielle d'une table dans une autre
    Par Tybaal dans le forum Débuter
    Réponses: 2
    Dernier message: 08/11/2011, 14h19
  2. Quellue interface pour travailler sur une grosse table ?
    Par grinder59 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 22/12/2006, 16h25
  3. statistique d'une grosse table
    Par dibejmaher dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 01/09/2006, 16h20
  4. Update trés lent sur une grosse table
    Par neo.51 dans le forum Oracle
    Réponses: 21
    Dernier message: 14/12/2005, 11h06
  5. [Oracle] Mieux vaut une grosse table ou plein de petite ?
    Par ShinJava dans le forum PHP & Base de données
    Réponses: 16
    Dernier message: 30/11/2005, 16h32

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