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 :

Performance requête SQL


Sujet :

Langage SQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Inscrit en
    Août 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 7
    Par défaut Performance requête SQL
    Bonjour,

    J'ai 2 questions portant sur la performance des requêtes SQL :

    - Mieux vaut-il faire une seule "grosse" requête (avec des jointures et des sous requêtes) que de faire plusieurs petites requêtes les unes à la suite des autres ?

    Je me dis que logiquement une grosse requête devrait être plus optimisée notamment car nous n'appelons qu'une fois notre sgbd mais cependant la requête est moins "maintenable"

    - Ensuite dans le cas où il serait plus judicieux de faire une grosse requête, pourriez-vous me dire la différence qu'il y a entre ces 2 requêtes :

    Modèle utilisé :
    SALARIE
    salarie_id
    salarie_name

    SALARIE_BUREAU
    id
    salarie_id
    bureau_id

    BUREAU
    bureau_id

    "
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT bureau_id FROM salarie_bureau WHERE salarie_id =
                                  SELECT salarie_id FROM salarie WHERE salarie_name = 'toto';
    "

    ou

    "
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT bureau_id FROM salarie_bureau 
                                  INNER JOIN salarie ON salarie_bureau.salarie_id = salarie.salarie_id
                                  WHERE salarie.name = 'toto'
    ;

    La première est une requête imbriquée, l'autre avec jointure. Ces 2 requêtes donnent-elles toujours le même résultat ? Quelle serait la plus performante des 2 ?

    Merci d'avance !

    remdel

  2. #2
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 197
    Billets dans le blog
    1
    Par défaut
    Il faut privilégier la réduction du nombre de requêtes, surtout lorsqu'elles sont indissociables : par exemple, il ne faut surtout pas chercher dans une requête l'identifiant d'un élément, et d'aller chercher les informations de l'élément dans une requête suivante, d'autant que généralement ça va te demander à faire plusieurs fois de suite les mêmes requêtes.

    Ensuite, il faut toujours privilégier au maximum les jointures (avec la norme SQL92, que tu as utilisé), plutôt que des sous-requêtes. D'autant que ta sous-requête peut provoquer des erreurs : il faut toujours utiliser champ IN (select ...) ou à la limite champ = (select MAX(...) ...)

  3. #3
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Il est évident qu'ici il faut faire une jointure !

    Le cas où il peut être plus intéressant de faire une sous requête est la recherche d'une existence ou d'une non existence.

    Par exemple, si tu recherches les bureaux inoccupés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT b.bureau_id
    FROM BUREAU b
    WHERE NOT EXISTS
    (
    	SELECT *
    	FROM SALARIE_BUREAU sb
    	WHERE sb.bureau_id = b.bureau_id
    )
    La requête précédente sera peut-être plus performante, s'il y a beaucoup de données, que cette requête avec jointure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT b.bureau_id
    FROM BUREAU b
    LEFT OUTER JOIN SALARIE_BUREAU sb ON sb.bureau_id = b.bureau_id
    WHERE sb.bureau_id IS NULL
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  4. #4
    Membre du Club
    Inscrit en
    Août 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 7
    Par défaut
    D'accord merci à vous 2 pour vos réponses !

    Concernant le choix entre la jointure ou la sous requête c'est :
    J'utilise la sous requête doit être utilisée lorsque je cherche à savoir si j'ai 0 ou 1 résultat et la jointure dans tous les autres cas c'est bien ça ?

    Remdel

  5. #5
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 197
    Billets dans le blog
    1
    Par défaut
    Non, pour faire une jointure quand tu as 0 ou 1 élément joint, il faut faire un LEFT OUTER JOIN.
    Les cas d'utilisation de sous-requête sont pour :
    - Tester l'existence d'une donnée, sans forcément qu'un lien existe explicitement. Par exemple rechercher tous les clients qui n'ont pas passé de commande de champagne depuis plus de 6 mois => Avec une jointure, ça ne sera pas très clair à la relecture.
    - On ne veut pas utiliser une requête analytique pour retrouver par exemple le détail de la commande qui le plus gros montant depuis le début du mois.

    En gros, dès que tu peux t'en passer, passe-t'en. Les problèmes de performances entre sous-requête et jointures/fonctions analytiques sont généralement en défaveur de la sous-requête, et cela varie pas mal d'un SGBD à l'autre.
    Le seul intérêt des sous-requêtes, quand on a l'habitude d'en utiliser, c'est qu'elles peuvent parraîtres plus claires à lire. Mais en programmation, c'est un bien pâle argument.

  6. #6
    Membre du Club
    Inscrit en
    Août 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 7
    Par défaut
    J'ai un peu de mal à saisir la différence entre "Tester l'existence d'une donnée" et tester si j'ai "0 ou 1 élement joint".

    Je vais prendre un cas concret. Soit le modèle suivant :

    User
    user_id
    user_name

    SalleSecurisee
    salle_id
    salle_name

    UserSalleSecurisee
    user_id
    salle_id

    Si une ligne est présente dans la table UserSalleSecurisee cela signifie que l'utilisateur a le droit d'accès à cette salle. Sinon il n'en a pas le droit.

    Je souhaite via une requête savoir si l'user "toto" a accès à la salle sécurisée "bunker". Cela revient à tester l'existence d'une ligne dans la table UserSalleSecurisee ou encore de vérifier s'il y a 0 ou 1 résultat.

    2 requètes possibles :
    Avec une sous requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Select * From UserSalleSecurisee uss
    	     Where uss.salle_id = 
    		     (Select s.salle_id From SalleSecurisee s Where s.salle_name = 'bunker')
    	     AND u.user_id =
    		     (Select u.user_id From User u  Where u.user_name = 'toto');
    Avec des jointures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Select * From User u
    	     INNER JOIN UserSalleSecurisee uss ON u.user_id = uss.user_id
    	     INNER JOIN SalleSecurisee s ON s.salle_id = uss.salle_id
    	     WHERE u.user_name = 'toto' 
    	     AND s.salle_name = 'bunker';
    Dans ce cas l'utilisation d'une sous requête est elle plus adéquate/performante qu'une jointure ?

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

Discussions similaires

  1. [WD17] Performance interface, requête sql trop longue, inutilisable.
    Par droliprane dans le forum WinDev
    Réponses: 28
    Dernier message: 08/09/2015, 12h04
  2. [2.x] requête sql, problème performance
    Par SuperArbre dans le forum Symfony
    Réponses: 3
    Dernier message: 14/01/2014, 08h59
  3. performance des requêtes SQL
    Par haykelFST dans le forum Développement
    Réponses: 3
    Dernier message: 20/10/2011, 18h28
  4. [12.5.4]Problème de performances sur requête SQL
    Par tdeco dans le forum Adaptive Server Enterprise
    Réponses: 5
    Dernier message: 25/05/2010, 22h06
  5. Performances requête SQL et parcours de ResultSet
    Par El Saigneur dans le forum JDBC
    Réponses: 9
    Dernier message: 17/05/2010, 15h54

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