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 :

[GOOD PRACTICE] Opérateur EXISTS et subquery


Sujet :

Langage SQL

  1. #1
    Membre confirmé Avatar de joKED
    Profil pro
    Imposteur en chef
    Inscrit en
    Février 2006
    Messages
    339
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Imposteur en chef

    Informations forums :
    Inscription : Février 2006
    Messages : 339
    Points : 458
    Points
    458
    Par défaut [GOOD PRACTICE] Opérateur EXISTS et subquery
    Bonjour,

    J'utilise régulièrement l'opérateur EXISTS avec sous requête lorsque je veux vérifier qu'une donnée est bien présente dans une table.

    Toutefois, j'ai vu plusieurs exemples d'utilisation de cet opérateur dans divers tutos cet opérateur, et je reste circonspect d'un point de vue performance sur la forme des sous requêtes utilisées.

    Voici plusieurs exemples :
    Exemple 1 avec SELECT * :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE EXISTS (SELECT * FROM MATABLE WHERE ...)
    Exemple 2 avec SELECT MON_FIELD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE EXISTS (SELECT MON_FIELD FROM MATABLE WHERE ...)
    Dans l'exemple 1, l'opérateur EXISTS reçoit une subquery qui renvoie tous les champs de la table. Je suppose qu'il s'agit d'une mauvaise pratique. Quel intérêt de ramener tous les champs pour simplement vérifier une existence ?

    Dans l'exemple 2, l'opérateur EXISTS reçoit une subquery qui renvoie un seul champ de la table. C'est déjà mieux AMHA. Toutefois, doit on privilégier le champs correspondant à la PK de la table ? Ou tout autre champs peut il faire l'affaire ? Quelle est la bonne pratique à ce niveau ?

    Vous remerciant par avance pour vos lumières.

    PS : Ceci n'est pas un débat sur l'opportunité d'utiliser EXISTS vs JOIN vs IN . Juste une question pour connaitre la meilleure manière de procéder lorsque l'on utilise EXISTS.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 338
    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 338
    Points : 39 726
    Points
    39 726
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Avec (NOT) EXISTS, la requête correlée ne transporte aucune donnée, seulement un booléen vrai/faux

    Du coup il n'y a aucune différence entre l'une et l'autre requête en termes de performances

    Cela étant, je préfère utiliser une constante, par exemple SELECT 1, pour bien mettre en évidence ce fonctionnement et aussi ne pas inciter les débutants à coder des SELECT *qui dans tout autre contexte sont à proscrire

  3. #3
    Membre confirmé Avatar de joKED
    Profil pro
    Imposteur en chef
    Inscrit en
    Février 2006
    Messages
    339
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Imposteur en chef

    Informations forums :
    Inscription : Février 2006
    Messages : 339
    Points : 458
    Points
    458
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Bonjour,

    Avec (NOT) EXISTS, la requête correlée ne transporte aucune donnée, seulement un booléen vrai/faux
    Ah, voilà le morceau d'information pertinent qui me manquait.

    Bien noté aussi pour l'idée d'utiliser une constante, c'est effectivement une très bonne idée.

    Merci beaucoup, ça répond parfaitement à mes interrogations.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    Coucou,
    Personnellement je prefere utiliser Select null dans les exists comme ça en lisant on voit bien qu'on se moque du contenu.
    Cordialement
    Soazig

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 338
    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 338
    Points : 39 726
    Points
    39 726
    Billets dans le blog
    9
    Par défaut
    Bonjour Soazig

    Pourquoi pas, mais comme je l'ai indiqué récemment dans un autre sujet, SELECT NULL n'est pas applicable sur tous les SGBD alors que SELECT constante l'est

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 897
    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 897
    Points : 53 135
    Points
    53 135
    Billets dans le blog
    6
    Par défaut
    Dans les cours que je donne je met souvent la forme suivante pour ce type de requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE EXISTS (SELECT 1/0 FROM MATABLE WHERE ...)
    Cela me permet de voir si le serveur SQL fait bien son boulot… Sur SQL Server ce 1/0 ne provoque aucune erreur, tout simplement parce que le contenu du SELECT n'est jamais lu, ce qui est le principe même de ce type de requête….
    Et moins le serveur SQL fait de chose, plus ça va vite !

    A +

  7. #7
    Membre confirmé Avatar de joKED
    Profil pro
    Imposteur en chef
    Inscrit en
    Février 2006
    Messages
    339
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Imposteur en chef

    Informations forums :
    Inscription : Février 2006
    Messages : 339
    Points : 458
    Points
    458
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Sur SQL Server ce 1/0 ne provoque aucune erreur, tout simplement parce que le contenu du SELECT n'est jamais lu, ce qui est le principe même de ce type de requête….
    C'est intéressant ça.
    Si je mets n'importe quelle expression syntaxiquement valide, ça fonctionne (genre 3x2 ou 40-5 ou 0 ou 1/0 ...)

    Mais par contre, si je mets un nom de colonne qui n'existe pas dans la table, j'ai une belle erreur m'indiquant que la colonne n'existe pas.

    Donc, le contenu du SELECT n'est jamais lu, mais si quand même un peu en fait . Enfin, il n'est pas lu, mais analysé alors ? (je dois pas avoir les bons termes je pense).

    PS : La question initiale est bien résolue, c'est juste pour ma culture personnelle.

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Je ne sais plus où j'ai lu que le "mieux" était d'utiliser "*" justement en raison de l'analyse des noms de colonne indiquées dans la sous-requête.
    => Avec *, le SGBD n'a pas besoin d'aller vérifier que le nom des colonnes existes ni que l'expression est une constante/expression valide.


    Auparavant, j'utilisais "null", mais les noobs qui passent derrière comprennent jamais et pensent qu'on vérifie qu'il n'y a rien, ou je ne sais quoi.
    Idem avec "1", y'en a qui vont encore croire qu'on cherche à compter les lignes, ou qu'on cherche à vérifier qu'il y en a une et une seule (c'est incroyable comme certains sont pas tous seuls dans leur tête).

    Le * a l'avantage que si tu dis aux noobs "tu écris une requête avec une * t'es viré", quand le gars se pointe tout fier en disant "oué ben vire-toi parce que t'as mis une étoile", ça donne l'occasion de lui expliquer comment fonctionne le EXISTS, alors que si tu lui expliques avant, il oubliera/n'écoutera pas.


    En revanche, le * est bien embêtant sous SQL Server, car tu ne peux pas compiler une procédure stockée "with schemabinding"... C'est vraiment dommage car comme l'a si bien dit SQLPro, OSEF ce qu'il y a dans le sous-SELECT... mais le compilateur n'est pas de cet avis.

    Du coup je crois que pour cette raison je vais me mettre aussi à utiliser 1/0... Comme ça, ça choquera toujours autant les noobs, sans pour autant faire râler le compilateur

  9. #9
    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
    Citation Envoyé par joKED Voir le message
    Si je mets n'importe quelle expression syntaxiquement valide, ça fonctionne (genre 3x2 ou 40-5 ou 0 ou 1/0 ...)
    Mais par contre, si je mets un nom de colonne qui n'existe pas dans la table, j'ai une belle erreur m'indiquant que la colonne n'existe pas.
    Il y a plusieurs étapes derrière l'exécution d'une requête, entre autre le parsing syntaxique, le parsing des objets puis l'interprétation.

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 897
    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 897
    Points : 53 135
    Points
    53 135
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Je ne sais plus où j'ai lu que le "mieux" était d'utiliser "*"
    Oui et non, ça dépend du SGBDR… La plupart analysent quand même les colonnes et faisant donc des requêtes de métadonnées pour rien…. Ce fut le cas de SQL Server dans les versions antérieurs à 2008 je crois.

    A +

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

Discussions similaires

  1. Quickstart et good practices
    Par niocco dans le forum Adaptive Server Enterprise
    Réponses: 4
    Dernier message: 22/09/2013, 18h24
  2. [2008R2] Question à propos de l'opérateur EXISTS
    Par Kropernic dans le forum Développement
    Réponses: 2
    Dernier message: 10/06/2013, 11h01
  3. Requête avec l'opérateur EXISTS
    Par Aiglon13 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 26/01/2011, 02h11
  4. Javac + surcharge d'opérateurs = ?..ça existe enfin
    Par infotunis dans le forum API standards et tierces
    Réponses: 14
    Dernier message: 10/08/2007, 12h56
  5. Réponses: 2
    Dernier message: 17/02/2007, 04h34

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