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 Firebird Discussion :

optimisation "UPDATE <> WHERE ID IN (SELECT <> )"


Sujet :

SQL Firebird

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Points : 12
    Points
    12
    Par défaut optimisation "UPDATE <> WHERE ID IN (SELECT <> )"
    Bonjour,
    J'utilise pas mal de requête du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    UPDATE MATABLE1 T1
    SET T1.FIELD = "QQC"
    WHERE T1.ID IN
    (
    SELECT T2.ID
    FROM MATABLE1 T2
    JOIN MATABLE2 T3
    ON T2.ID = T3.T2ID
    WHERE <conditions plus ou moins complexe...>
    )
    En fait, de souvenir, je passe par là car je suis en Firebird 2.1 et le moteur n'accepte pas de faire des UPDATE sur plusieurs tables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE MATBLE1 T1,MATABLE2 T2
    SET T1.FIELD = "QQC"
    WHERE T1.F1 =... AND T2.F3 = ....
    Ou même en passant par des JOIN au niveau de l'UPDATE, il rejette la requête

    Le truc c'est qu'en passant par une sous-requête et en faisant WHERE ID IN (liste ID résultat d'une requête)
    J'ai l'impression, en fait vu les statistique du résultat, c'est pas qu'une impression, qu'il exécute la sous-requête autant de fois qu'elle ne contient de résultat. Du coup, le temps d'exécution est énorme et est proportionnel au nombre de resultat de sou-requête.
    Actuellement j'arrive à optimiser manuellement en exécutant la sous-requête, en copiant les résultats en y insérant une virgule et j'exécute l'UPDATE avec la liste des ID copiés.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE MATABLE1 T1
    SET T1.FIELD = "QQC"
    WHERE T1.ID IN
    (234234,46573,23545,24567,5674578,65463,245654,....)
    Efficace, mais laborieux :o/

    N'y a-t-il pas un autre moyen pour faire ce genre de chose ?
    Merci d'avance

    Hervé

    [EDIT] oublié le IN dans WHERE

  2. #2
    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
    Je l'écrirais plutôt comme ça, inutile de repasser sur matable1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UPDATE MATABLE1 T1
       SET T1.FIELD = 'QQC'
     WHERE exists (SELECT 1
                     FROM MATABLE2 T3
                    where T1.ID = T3.T2ID
                      and <conditions plus ou moins complexe...>
                  )
       and <autres conditions>
    Sinon il est également possible d'utiliser MERGE en ne précisant que la clause WHEN MATCHED, surtout utile quand la nouvelle valeur (ici QQC) provient d'une requête sur la table matable2.

    [EDIT] Au fait je ne connais pas firebird, la doc sur merge concerne la 2.5, je ne sais pas si le fonctionnement est identique en 2.1

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Merci skuatamad
    Je vais essayer ça.
    Effectivement, tu fais bien de préciser, j'ai l'impression que Firebird est en évolution perpétuelle, à la mode JAVA, du coup, suivant les versions, il y a des choses disponibles, d'autres non, d'autres plus...

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Je ne vois pas très bien le fonctionnement du SELECT 1 ?
    Tu pourrais expliciter ?
    Merci

  5. #5
    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
    Avec EXISTS il n'est pas nécessaire de sélectionner des colonnes dans la sous-requête : EXISTS and SINGULAR
    The EXISTS predicate returns true if the result set of the subselect contains at least one row. If it is empty, EXISTS returns false.
    Moi j'utilise 1 dans la sous-requête, d'autres NULL ou 'X', ou encore * mais je n'aime pas * qui fait un appel au dictionnaire (en tout cas il me semble que c'est vrai sur Oracle).

    Et puis 1 ou NULL montre bien que la logique n'est pas dans les colonnes sélectionnées mais dans la corrélation entre les 2 requêtes.

    Sinon tu peux aussi utiliser IN :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UPDATE MATABLE1 T1
       SET T1.FIELD = 'QQC'
     WHERE T1.ID in (SELECT T3.T2ID FROM MATABLE2 T3 WHERE <conditions plus ou moins complexe...>)
       AND <autres conditions>

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Alors, désolé, j'avais oublié le IN dans la première requête de mon post.
    J'utilise actuellement la méthode du WHERE T1.ID IN(SELECT. . . )
    Et c'est justement l'objet de mon post car cette méthode prend énormément de temps car il semble que le moteur Firebird exécute la sous-requête autant de fois que le nombre de résultat de cette sous-requête, enfin c'est une supposition.
    Mais plus il y a de résultats, plus ça prend des plombe.
    Je vais essayer ton autre solution.

Discussions similaires

  1. [Optimisation] Requête Update
    Par plutonium719 dans le forum Développement
    Réponses: 2
    Dernier message: 01/04/2008, 15h53
  2. [Optimisation] Requête Update
    Par plutonium719 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/04/2008, 15h53
  3. optimisation requête update
    Par besco dans le forum Oracle
    Réponses: 4
    Dernier message: 14/02/2008, 09h01
  4. Réponses: 1
    Dernier message: 05/10/2007, 09h49
  5. [SYBASE] optimisation requete UPDATE
    Par metheorn dans le forum Sybase
    Réponses: 8
    Dernier message: 24/05/2004, 17h01

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