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 :

Update and exists [12c]


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 42
    Par défaut Update and exists
    Bonjour,

    lors d'une mise à jour d'une colonne de table à partir d'un sous-select, est-ce qu'il y a un intérêt à ajouter une condition EXISTS pour vérifier si la jointure retourne quelque chose.

    Est-ce qu'il y a un impact performance à l'utilisation de la clause exists dans ce cas de figure ? Et si oui lequel ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Update perf_tab1 t0
    set
    t0.object_type = (select t1.object_type from perf_tab2 t1 where
    t1.object_id = t0.object_id) where
    exists (select 1 
    from perf_tab2 t1 where
    t1.object_id = t0.object_id);

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 175
    Par défaut
    Bonjour,

    Oui bien sûr qu'il y a un intérêt. Sans clause WHERE toutes les lignes de la table seront mises à jour. Donc si ton sous-select ne ramène rien pour certaines id, alors tu mettras NULL dans object_type. Si c'est le but recherché, alors en effet la condition EXISTS n'est pas nécessaire.
    Quand je dois faire une mise à jour de données pour lesquelles j'ai besoin des données source pour la mise à jour, j'utilise un MERGE, moins coûteux car données source lues qu'une fois (et syntaxe plus souple aussi);

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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 454
    Par défaut
    Et merge fusionne des mini-index avec les index de la cible à la fin au lieu de les mettre à jour ligne à ligne.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 42
    Par défaut
    Merci pour vos retour

    J'avais été au plus simple mais la table mise à jour est bien conditionné ppour ne mettre à jour que certains enregistrements (ici j'ai ajouté pour l'exemple object_type = 'TABLE').

    Dans ce cas de figure, les lignes de ma table t0 qui n'ont pas de correspondances dans t1 seront mises à jour avec Object_type à null si je ne mets pas de clause EXISTS ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Update perf_tab1 t0
    set
    t0.object_type = (select t1.object_type from perf_tab2 t1 
    where
    t1.object_id = t0.object_id) 
    where
    exists (select 1 
    from perf_tab2 t1 where
    t1.object_id = t0.object_id)
    and t0.object_type = 'TABLE';
    Si je suis en mesure de garantir qu'il y a un correspondance, du coup il ne faut mieux pas utiliser EXISTS ? J'ai bon ?

    Pour l'utilisation avec MERGE j'ai essayé avec ces instructions,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MERGE INTO perf_tab1 t0
      USING perf_tab2 t1
      ON (t0.object_id = t1.object_id) 
      WHEN MATCHED THEN
        UPDATE SET t0.object_type = t1.object_type WHERE t0.object_type = 'TABLE';

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 42
    Par défaut
    Les tests effectués sont sans appel :

    Ecoulé : 00:00:00.415 avec l'utilisation du merge
    Ecoulé : 00:06:33.682 avec update classique sans utilisation du EXISTS
    Ecoulé : 00:06:38.002 avec update et utilisation du EXISTS

    Les tests confirment bien une mise à jour à null si pas de correspondance trouvé entre la table mise à jour et a table de référence.

    @WALDAR : Peux-tu STP préciser "Et merge fusionne des mini-index avec les index de la cible à la fin au lieu de les mettre à jour ligne à ligne."

  6. #6
    Membre Expert
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 175
    Par défaut
    Tu vois que le MERGE est non seulement plus pratique, mais il est plus rapide ici.
    J'utilise UPDATE uniquement quand je dois mettre à jour avec des valeurs en dur, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE t
    set status = 2, modification_date = sysdate
    WHERE ....
    Si les valeurs servant à la mise à jour proviennent d'autres tables, alors j'utilise MERGE, comme dans ton exemple.

  7. #7
    Membre Expert

    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
    Par défaut
    Citation Envoyé par grouhan Voir le message
    Les tests effectués sont sans appel :

    @WALDAR : Peux-tu STP préciser "Et merge fusionne des mini-index avec les index de la cible à la fin au lieu de les mettre à jour ligne à ligne."
    Lorsque le MERGE peut se faire en "direct path load" (via l'utilisation du hint append par exemple) les indexes sont maintenus en bulk à la fin du MERGE (ou de l'INSERT)

    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
     
    MERGE /*+ append */ INTO t2  
        USING (SELECT * FROM t1) h
        ON (t2.n1 = h.n1)
      WHEN MATCHED THEN
        UPDATE SET t2.d1 = h.d1
      WHEN NOT MATCHED THEN
        INSERT (n1, d1)
        VALUES (h.n1, h.d1);
     
    10 rows merged.
     
    SQL> select * from t2;
    select * from t2
                  *
    ERROR at line 1:
    ORA-12838: cannot read/modify an object after modifying it in parallel
    Dans le modele que j'ai présenté plus haut les 10 lignes mergées l'ont été via un INSERT. Et comme je ne peux pas séléctionner de la table t2 avant de commiter cela veut dire que l'INSERT a bien été fait en "direct path load". Et dans ce cas la maintenance des indexes est plus performante.

    Bien Cordialement
    Mohamed

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

Discussions similaires

  1. Update and Commit
    Par olifile dans le forum Linq
    Réponses: 3
    Dernier message: 29/07/2009, 09h23
  2. Impossible de generer insert, update and delete sqldatasource
    Par samiblh dans le forum Accès aux données
    Réponses: 0
    Dernier message: 20/05/2009, 00h16
  3. update si existe, insert sinon
    Par identifiant_bidon dans le forum Langage SQL
    Réponses: 3
    Dernier message: 26/10/2007, 11h33
  4. [MySQL] update and rand by
    Par morgan47 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 02/04/2007, 22h58
  5. msg d'erreur : "Incorrect usage of UPDATE and LIMIT"
    Par ident dans le forum Requêtes
    Réponses: 1
    Dernier message: 29/10/2006, 19h13

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