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

Langage SQL Discussion :

Optimisation d'un not in


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2009
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 194
    Points : 102
    Points
    102
    Par défaut Optimisation d'un not in
    Bonjour à tous.

    Je suis vraiment mauvais en SQL et je voudrais optimiser ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * 
    FROM [last].[ProductTab]
    where PartnumberID+TabID+UserTypeID+AttributeID not in (
    SELECT PartnumberID+TabID+UserTypeID+AttributeID   
    FROM [now].[ProductTab])
    En gros je veux toutes les occurrences qu'il y à dans la table du schéma last mais pas dans now.
    J'ai bien vu qu'on pouvait utiliser des left join, mais je n'arrive pas au résulta escompter.
    J'ai essayer avec un not exist plutôt mais c'est encore trop long.

    Une idée ?

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 344
    Points : 39 742
    Points
    39 742
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Oubliez le not in

    Préférez soit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT Col1
         , Col2
         , ...
         , Coln
    FROM last.ProductTab  as T1
    where not exists
         (select 1
          from now.ProductTab as T2
          where T2.PartnumberID = T1.PartnumberID)
    Soit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT Col1
         , Col2
         , ...
         , Coln
    FROM last.ProductTab  as T1
    LEFT OUTER JOIN now.ProductTab as T2
      on T2.PartnumberID = T1.PartnumberID
    WHERE T2.PartnumberID is null
    En évitant les select *, peu performants et dangereux car le résultat est instable

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 902
    Points : 53 143
    Points
    53 143
    Billets dans le blog
    6
    Par défaut
    Vous n'arriverez jamais à optimiser cette requête parce que la jointure (le IN est une forme de jointure) s'effectue sur des calculs scalaire ce qui impose une itération alors que les SGBDR fonctionnent en mode ensembliste (manipulation et rapprochement de valeurs).

    Si vous voulez des performance et ce quelque soit l'écriture de votre requête il faut que vous vous débarrassiez de cette imbécilité de calcul :
    "PartnumberID+TabID+UserTypeID+AttributeID"

    Si ce sont des littéraux (comme je le soupçonne), alors faites une triple comparaison. Car dans votre cas c'est une imbécilité majeure qui peut conduire à des résultats faux.

    Si ce sont des entiers, le cas est désespéré !

    A +

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    Pour moi, il faut passer par le Not Exists. Prendre la requête d'escartefigue, en mettant bien sûr les 4 conditions de jointure sur PartnumberID, TabID, UserTypeID et AttributeID dans le where.
    A la rigueur, sous Oracle, la syntaxe suivante fonctionne, mais pas sous tous les SGBD :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WHERE (PartnumberID, TabID, UserTypeID et AttributeID) 
    NOT IN (SELECT PartnumberID, TabID, UserTypeID et AttributeID
                FROM [now].[ProductTab])
    C'est sympa pour des requêtes à la volée, mais pour anticiper un potentiel déploiement sur une autre base (un jour dans plusieurs années), ce serait sympa pour le futur développeur (ça pourrait être moi ?) de faire une requête standard SQL en not exists


    Dans tous les cas la requête initiale est fausse, et il faut absolument la changer. Par exemple, si ce sont des entiers :

    1 + 2 + 3 + 4

    Matche avec 1 + 3 + 4 + 2. Fonctionnellement, c'est faux !



    Même avec des littéraux, en admettant que votre SGBD accepte "+" en tant qu'opérateur de concaténation (genre H2).

    'a' + 'bc' + 'd' + 'e'

    Matche avec 'a' + 'b' + 'cd' + 'e'. Pareil, fonctionnellement, c'est faux ! Il faudrait a minima séparer par des tirets (mais ne le faites pas, utilisez plutôt not exists)

Discussions similaires

  1. Optimisation requête jointure NOT IN
    Par pop_up dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 05/11/2014, 16h41
  2. optimisation question de rapidité (<> vs not)
    Par Just-Soft dans le forum Langage
    Réponses: 5
    Dernier message: 20/11/2008, 11h51
  3. Optimisation de requête decode not in decode
    Par Kiroukool dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/09/2007, 11h10
  4. [Oracle 9i] Optimisation clause not exists
    Par mjolymelot dans le forum Langage SQL
    Réponses: 7
    Dernier message: 23/08/2006, 17h20
  5. Optimiser requête utilisant NOT IN
    Par Neilos dans le forum Langage SQL
    Réponses: 5
    Dernier message: 11/08/2005, 14h24

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