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

Administration Oracle Discussion :

Problème de performance lors de suppression/insertion


Sujet :

Administration Oracle

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2006
    Messages : 69
    Points : 43
    Points
    43
    Par défaut Problème de performance lors de suppression/insertion
    Bonjour à tous,

    Sous Oracle 10g (SE 10.2.0.1), EM nous indique quelles sont les requêtes qui consomment le plus de ressource.

    Depuis quelques temps, je trouve régulièrement les mêmes objets responsables de lenteurs.

    "EM" m'indique les éléments suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Aktion  Investigate application logic involving I/O on INDEX "IDINFO.SD_DWH_STAT_PREST_CASANNEE_IDX" with object id 369455.   
     Datenbankobjekt IDINFO.SD_DWH_STAT_PREST_CASANNEE_IDX 
     
    Begründung  The I/O usage statistics for the object are: 0 full object scans, 23558 physical reads, 9449 physical writes and 0 direct reads. 
    Begründung  The SQL statement with SQL_ID "04maspp34qdtf" spent significant time waiting for User I/O on the hot object. 
     SQL-Text BEGIN dbms_sqltune.execute_tuning_task(:1); END; 
    SQL ID 04maspp34qdtf
    N'ayant pas d'expérience dans ce domaine, je ne sais pas comment aborder la problématique. Après plusieurs recherches sans succès sur la toile, j'espère trouver la réponse sur ce forum!

    La problématique n'est pas lié qu'à cet indexe, parfois la table ou d'autres indexes de cette table posent également des problèmes.

    La table est constituée, actuellement, d'env. 7 millions de lignes. Chaque soir, on supprime env. 2 millions de lignes avant d'en insérer autant (Consolidation de données sur une année)!

    J'ai pu lire que la suppression en masse peut générer de la segmentation. "EM" me propose bien d'effectuer un "shrink" pour récupérer la place perdue (si j'ai bien compris). Un "shrink" ne vas pas nécessairement résoudre mon problème si je l'effectue tous les soirs.

    D'avance je remercie toutes personnes qui pourrait me donner une piste à explorer ou une méthodologie d'analyse pour déterminer où se situe le "hic".

    Excellent week-end à tous,

    Cédric

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Je vous conseille de supprimer votre index avant de supprimer / insérer vos données puis de le recréer après.

    Vous allez gagner du temps.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2006
    Messages : 69
    Points : 43
    Points
    43
    Par défaut
    Bonjour Waldar,

    J'avais également pensé à cela et après quelques recherches, j'avais trouvé une démonstration où la suppression des indexes et leur recréation était encore plus coûteuse que la suppression avec les indexes existant.

    J'avais donc décidé de ne pas implémenter cette solution.

    Sur vos conseils, j'ai modifié la procéudre en conséquence et je vérifierai demain le résultat.

    Merci et je vous tiendrai au courant!

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2006
    Messages : 69
    Points : 43
    Points
    43
    Par défaut
    Hello,

    @Waldar : Merci pour ce conseil!

    Le traitement est passé d'un peu plus de 13h à ~5h30! Le changement est impressionnant.

    J'ai encore un problème de segmentation sur la table elle-même. Y aurait-il un moyen pour le solutionner?

    Dois-je modifier les paramètres de création des segments automatique (pctfree, ...) où dois-je reconstruire la table de temps en temps?

    D'avance merci pour vos conseils.

    Salutation à tous!

  5. #5
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    Bonjour,

    si je devais régulièrement faire ce genre d'opération j'utiliserait une table partitionnée pour faire le travail.

    Imaginons que la table sur laquelle vous travaillez s'appelle source.

    Je commencerait par créer définitivement une table travail contenat une seule partition et de même structure que source.

    En supposant que ID est la clé primaire de source:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    create table travail as (select * from source where 1=2)
    partition by range (ID)
    (PARTITION P1 VALUES LESS THAN (MAXVALUE));
    A partir de là je réécrirais mon batch en 3 étapes :

    1°) Alimentation de la table de travail à partir des lignes de sources que l'on souhaite garder.

    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
     
    -- truncate de la table de travail
    truncate table travail ;
     
    -- suppression des contraintes de la table
    alter table travail disable constraint C1;
    alter table travail disable constraint C2;
    ...
    alter table travail disable constraint Cx;
     
    -- suppression de tous les index de la table de travail 
    drop index I1;
    drop index I2;
    ...
    drop index Ix;
     
    Insert /*+ APPEND */ into travail
    select * from source where <conditionws de conservation des lignes> ;
    commit;
    2°) J'alimenterais la table de travail avec les 2 millions de lignes à ajouter de préférence en mode direct.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Insert /*+ APPEND */ into travail <lignes à ajouter> ;
    commit;
    3°) J'effectuerais un échange de partitions avec la table source afin de l'alimenter avec un table à jour.

    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
     
    -- recréation des index
    create index I1 on travail(champ1, champ2, ... champx) .... ;
    create index I2 on travail(champx2, champy2, ... champz2) .... ;
    ...
    create index Ix on travail(champxx, champyx, ... champzx) .... ;
     
    -- recréation des contraintes
    alter table travail enable constraint C1;
    alter table travail enable constraint C2;
    ...
    alter table travail enable constraint Cx;
     
    -- calcul des statistiques sur la table
    exec dbms_stats.gather_table_stats (user, 'TRAVAIL', .... );
     
    -- Echange des partitions
    alter table travail exchange partition P1 with table source;
     
    -- nettoyage de la table travail
    truncate table travail ;
    ATTENTION : il est plus que préférable de tester ce genre d'opération en dehors des environnements de production d'une part, et d'autre part cette méthode ne fonctionne que si on est certain que la table source n'est pas mise à jour par un autre batch ni par un utilisateur pendant le traitement.

  6. #6
    Membre actif Avatar de Ahmed AANGOUR
    Homme Profil pro
    DBA Oracle
    Inscrit en
    Janvier 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : DBA Oracle

    Informations forums :
    Inscription : Janvier 2010
    Messages : 139
    Points : 271
    Points
    271
    Par défaut
    Il y'a plusieurs manières d'améliorer des DELETE+INSERT.
    il faut les étudier et les tester car ils dépendent de votre requête et des problématiques de votre application.
    Les solutions à étudier qui me viennent à l'esprit sont:
    - le partitioning
    - le parallélisme
    - le DIRECT PATH INSERT (via le hint APPEND)
    - l'insert en mode bulk

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    En plus de ce qui a été dit, j'ajouterai que si la table ne subit jamais de mise à jour, vous pouvez positionner votre PCTFREE à 0.

    En fait l'idée développée par ojo77, c'est que lorsqu'on atteint un certain volume de suppressions à effectuer, la meilleur solution c'est justement de ne pas en faire.

    Une autre solution serait, si vous conservez une année glissante dans votre table, de regarder du côté du partitionnement (à la semaine, au mois, à étudier selon vos données) afin de faire des truncates partitions (très rapides) combinés aux insert append.
    Avec des index locaux vous n'aurez pas à les recréer.

    Vous pouvez également compresser votre table (en 10g cela se limite aux chargement direct load il me semble): le chargement sera peut-être un peu plus long (d'un petit facteur), mais au final vous utiliserez moins de blocs de données ce qui accélérera les lectures : comme il s'agit d'un datawarehouse ou datamart, c'est toujours une bonne chose.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2006
    Messages : 69
    Points : 43
    Points
    43
    Par défaut
    Bonjour à tous,

    Un grand MERCI pour toutes ces réponses.

    Mon unique question en rapport aux solutions que vous soumettez, est-ce qu'elles sont compatibles avec Oracle Standard Edition?

    Il me semble, et j'espère me tromper, que le parallélisme et le "partionning" ne sont valable que pour Oracle Enterprise Edition, non?

    Dans l'attente de votre confirmation ou infirmation, je testerai les solutions "DIRECT PATH INSERT" et l'insertion en mode "bulk".

    Encore merci pour ce panel de solution.

    Salutations à tous.

  9. #9
    Membre expérimenté Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Points : 1 597
    Points
    1 597
    Par défaut
    En effet en SE pas de partitionning, on peut remplacer l'échande de partition par le renomage de tables mais c'est moins propre

Discussions similaires

  1. [Unitils] [TestNG][DBUnit][JPA][Hibernate] problème de sequence lors d'un insert.
    Par Faiche dans le forum Tests et Performance
    Réponses: 1
    Dernier message: 19/10/2009, 16h39
  2. Réponses: 1
    Dernier message: 29/07/2009, 22h20
  3. [Système] Problème de doublon lors d'un insert (voir fin)
    Par gregory.bts dans le forum Langage
    Réponses: 7
    Dernier message: 04/08/2007, 03h05
  4. Réponses: 4
    Dernier message: 02/03/2007, 11h35
  5. Réponses: 15
    Dernier message: 19/02/2007, 14h13

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