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 :

Performance d'un update de plusieurs colonnes en full scan


Sujet :

SQL Oracle

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut Performance d'un update de plusieurs colonnes en full scan
    Bonjour,

    N'arrivant pas à trouver de solutions à mon problème, je finis par venir demander de l'aide car je n'avance plus. J'ai une table sur laquelle je dois mettre à jour plusieurs colonnes. Toutes les lignes doivent être mises à jour. Comme je dois faire un full scan pour mettre à jour chaque colonnes, je mets à jour toutes les colonnes avec un seul update. J'ai donc une requête de ce type là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    update matable set
    col1 = case ... when ... else ... end,
    col2 = case ... when ... else ... end,
    col3 = case ... when ... else ... end,
    col4 = case ... when ... else ... end;
    Sur Oracle 10g, cet update mettait juste deux fois plus de temps que la mise à jour d'une colonne, 1h00 on va dire.

    Depuis le passage à Oracle 11g, la mise à jour met à peut près 15h alors que la mise à jour d'une colonne met toujours 0h30. Il devient en fait plus rentable de mettre à jour toutes les colonnes séparément.

    Je me demandais donc ce qui pouvait cause ce problème de performances ou si vous aviez des pistes de recherche.

    Pour ce que ca vaut, le plan d'exécution est le même que je mette à jour une ou toutes les colonnes.

    Merci d'avance!!

  2. #2
    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
    Difficile à dire ce qui ne va pas avec seulement ces informations. Un petit exemple sera bien venu.
    Il est plus performant de récréer une table que de mettre à jour tous ces lignes.

  3. #3
    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
    Je rejoins Mnitu, l'expérimentation montre qu'à partir de 5 % des blocs modifiés (en mode direct) ou 15 % (avec logging contraint) il est plus intéressant de recréer un table dans laquelle les données sont à jour et de l'échanger ensuite avec l'originale.

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Je mets à jour 25 colonnes sur 260, de tout type (des objets géométriques, des varchars, des integer). Cependant, les colonnes ne sont pas remplies avant la mise à jour et sont toutes à null car je viens de les créer. Je ne peux pas les remplir avant malheureusement.

    J'aimerai mettre un exemple mais la requête est trop important et trop lié au projet pour la modifier simplement.

    Je vais tester la création d'une autre table. Merci, je compléterai si ca ne marche toujours pas.

  5. #5
    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 394
    Points
    18 394
    Par défaut
    Vous n'avez pas un problème de PCTUSED / PCTFREE sur votre tablespace en 11g ?

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Possible, je ne connais pas ces paramètres. Je me renseigne mais si je comprends leur signification, je ne vois pas comment les consulter.

    edit: Sous oracle 11g pour cette table j'ai ceci:
    PCT_FREE 10
    PCT_USED null

    Pareil sous oracle 10g

  7. #7
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Points : 1 359
    Points
    1 359
    Par défaut
    Citation Envoyé par Gnatit Voir le message
    Bonjour,

    Depuis le passage à Oracle 11g, la mise à jour met à peut près 15h alors que la mise à jour d'une colonne met toujours 0h30. Merci d'avance!!
    Bonjour,

    Comme cela a déjà été signalé, il est difficile de se faire une idée quant aux causes ayant entrainé cette lenteur manifeste de votre update suite à votre migration de base de données de 10g vers 11g. Mais quelqu'ait été la methode utilisée pour faire cette migration, beaucoup de choses auquelles vous ne vous attendiez pas peuvent surgir à la fin de cette migration. Vous ne parlez pas des indexes qui existent sur cette table? ont-ils changé de définition? les données (clustering factor) ont-elles été eparpillées lors de cette migration? pas de where clause dans cet update, quelle type de table, etc... Vous ne "postez" pas aussi l'explain plan suivi par cet update.

    Néamoins, avez vous vérifié, les nouvelles valeurs des paramètes de l'optimisateur qui sont par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      (a) db_file_multiblock_read_count
      (b) optimizer_index_cost_adj
      (c) optimizer_index_caching
    en 11g par rapport à ce que vous aviez en 10g?

    Avez-vous tentez de faire votre update en utilisant le hint
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       /*+ optimizer_features_enable('10.2.0.4') */
    10.2.0.4 doit correspondre à la base que vous aviez avant la migration

    Bien cordialement

    Mohamed Houri

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Si il y a eu des problèmes lors de la migration (il y en a eu), ils ne devraient pas avoir d'effets sur cette table car elle est recréée toutes les semaines et donc a été créée sous oracle 11g.

    Les paramètres que vous citez sont les mêmes sous oracle 10g et 11g, respectivement 16, 100 et 0.

    Je ne connaissais pas ce hint, je vais essayer. J'aurais d'ailleurs du préciser que j'utilise deux hints pour l'update: /*+ FULL(matable) PARALLEL(matable, DEFAULT) */

    Merci beaucoup pour ces réponses.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Pour information, en créant une nouvelle table copie de la première mais en mettant à jour les colonnes, je suis passé de 15h à 12 minutes. Je ne pensais pas qu'Oracle s'empêtrait autant avec les updates

  10. #10
    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
    Faites une trace étendue de votre requête en 11g pour apprendre ce qui se passe.

  11. #11
    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
    Citation Envoyé par mnitu Voir le message
    Faites une trace étendue de votre requête en 11g pour apprendre ce qui se passe.
    Oracle met à jour l(es) index à chaque foi qu'une ligne est mise à jour sauf dans le cas où l'update utilise un filtre sur une colonne indexée et qu'il utilise l'index.

  12. #12
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2011
    Messages : 146
    Points : 263
    Points
    263
    Par défaut
    Bonjour,

    Quelle est la volumétrie de la table concernée ?
    Cette dernière était de combien avant migration ?

    Ce temps de 15 h est il systématique ?

    y a-t-il des traitements en parallèle de votre Update (transactions / batch ) ? présence de Locks ?

    cordialement.

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    La table fait 2,5 millions de lignes, autour de 2Go. Elle a été créée après migration comme elle est recréée toutes les semaines. Les performances pour la créer était cependant meilleur avant migration. Le temps de 15h est systématique et il n'y a pas d'autres traitements en parallèles.

    Mais la solution de créer une autre table est finalement plus que satisfaisante puisque les perfs sont bien meilleures que ce que j'avais avant sur oracle 10g. Même si bien sur il y a la frustration de ne pas avoir compris

    Merci à tous.

  14. #14
    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 394
    Points
    18 394
    Par défaut
    Je rebondis sur votre sujet car j'ai quand même quelques choses qui me chiffonnent, à mon avis c'est sur la conception que vous avez un problème :
    Citation Envoyé par Gnatit Voir le message
    Je mets à jour 25 colonnes sur 260, de tout type (des objets géométriques, des varchars, des integer). Cependant, les colonnes ne sont pas remplies avant la mise à jour et sont toutes à null car je viens de les créer. Je ne peux pas les remplir avant malheureusement.
    Dans ce cas, pourquoi tout simplement votre table principale ne ferait pas 235 colonnes (ce qui est déjà très gros), et vous créeriez une seconde table avec les 25 colonnes calculées après coup (plus la clef primaire) ?
    Une simple vue relie vos deux tables, et vous n'y voyez plus du feu.

    D'ailleurs votre update, quel genre de calcul fait-il ? Il va dans d'autres tables où il utilise les données présentes dans les autres colonnes ?

  15. #15
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Je comprends bien que a vous chiffonne, la conception n'est pas de moi et je suis encore débutant on va dire. La solution des 25 colonnes dans une autre table a été envisagée. Mais pour correspondre au modèle d'une autre table, elles ont été mises dans la même table. Je n'avais pas pensé à la vue, ca règlerait le problème.

    Les calcul sont faits à partir d'autres colonnes de la même table (et de la même ligne). Le but est d'accélérer des recherches sur la table, il y a donc des concaténations de colonnes pour des recherches de textes, des conversions de valeurs numériques, des comparaisons de valeurs, des case when pour déduire des valeurs booléennes, des créations d'objets géométriques.

    Ces calculs ne peuvent se faire avant au remplissage de la table car il y a des conditions dépendant de la globalité de la table (présence de doublons sur certaines colonnes), conditions précalculées par un update préalable pour que tout puisse se faire ligne par ligne.

    En dehors de la mauvaise conception, mon problème a surtout été ces deux questions:
    - pourquoi faire l'update en plusieurs fois est plus efficace alors que toutes les lignes sont systématiquement parcourus
    - pourquoi cette différence entre Oracle 10g et 11g

    La solution de la recréation de la table me permet de corriger au plus vite, et je ne sais si j'aurai le temps de refaire des tests pour expliquer les 15h, surtout que bloquer la machine 15h c'est long!

    Encore merci.

  16. #16
    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 394
    Points
    18 394
    Par défaut
    Citation Envoyé par Gnatit Voir le message
    Ces calculs ne peuvent se faire avant au remplissage de la table car il y a des conditions dépendant de la globalité de la table (présence de doublons sur certaines colonnes), conditions précalculées par un update préalable pour que tout puisse se faire ligne par ligne.
    Ok, c'est une information intéressante.

    Vous pourriez aussi mettre ces calculs dans une vue, ou avec Oracle 11g directement dans des colonnes virtuelles.

    Dans la vue le calcul est effectué au moment de la sélection, dans le cas des colonnes virtuelles le calcul est effectué au moment de la mise à jour des autres colonnes.

    Il faudrait voir si tout simplement vous pouvez supprimer la phase de mise à jour avec l'une de ces deux méthodes.

    Un petit exemple :
    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
    create table tbl
    (
        c1   number(1),
        c2   number(2),
        c3   as (c1 * c2)
    );
    -- Table created.
     
    insert into tbl (c1, c2) values (2, 4);
    -- 1 row created.
     
    select c1, c2, c3 from tbl;
     
            C1         C2         C3
    ---------- ---------- ----------
             2          4          8
    -- 1 row selected.
     
    update tbl set c1 = 9;
    -- 1 row updated.
     
    select c1, c2, c3 from tbl;
     
            C1         C2         C3
    ---------- ---------- ----------
             9          4         36
    -- 1 row selected.
     
    drop table tbl;
    -- Table dropped.
    Aussi dès lors que vous avez fini vos mises à jour sur vos autres colonnes, vos vingt-cinq dernières sont déjà renseignées.
    Reste à voir le coût, pour ça je n'en ai pas la moindre idée, mais ça peut être une piste, même si j'ai bien compris que les 12 minutes de la recréation de votre table vous sont satisfaisantes.

    Une précision, les colonnes virtuelles peuvent être indexées !

  17. #17
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Points : 3
    Points
    3
    Par défaut
    Les colonnes virtuelles sont une solutions très intéressantes. Nous avions déjà essayé avec une vue mais les performances étaient trop mauvaises lors de l'accès à la table.

    Par contre, étant donné que l'on ajoute toutes les lignes au début (plus d'ajouts par la suite), qu'on fait les updates et qu'il manque des informations tant que toute la table n'est pas rempli, je ne peux faire l'ajout de colonnes virtuelles qu'à la fin. Dans ce cas, leur calcul reviendrait à un update final je pense comme je faisais actuellement. Mais pour plus tard c'est bien noté!

Discussions similaires

  1. probleme de mise a jour update de plusieur colonnes
    Par perrotta dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/12/2009, 12h16
  2. UPDATE sur plusieurs colonnes à la fois
    Par yuukuari dans le forum Requêtes
    Réponses: 8
    Dernier message: 18/11/2009, 15h46
  3. Performance d'un update sur une colonne
    Par melendil dans le forum DB2
    Réponses: 2
    Dernier message: 31/03/2009, 15h41
  4. Requete update plusieurs colonnes sql paradox
    Par vitch8 dans le forum Paradox
    Réponses: 1
    Dernier message: 06/03/2009, 18h35
  5. Update de plusieur colonne d'une meme table
    Par Poisson59 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 28/09/2006, 10h25

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