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 :

Comment optimiser cette simple jointure


Sujet :

Langage SQL

  1. #1
    Membre averti
    Avatar de if_zen
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2004
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 275
    Points : 316
    Points
    316
    Par défaut Comment optimiser cette simple jointure
    Bonjour à tous !

    Voici un schéma de données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    [employee] -- count : 384398
    - id
    - idteam
    - sinceDate
    - idservice
     
    [service] -- count : 605
    - id
    - idcompany
     
    [company] -- count : 128
    - id
    Chaque table a son index défini sur les colonnes ID* (id, idteam, idservice, etc)

    Maintenant une requete, qui me parait simple. Je cherche tous les idteam uniques de la table employee dont l'idcompany est 42.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select E.idteam, min(E.sinceDate)
    from employee E
    left join service S on (E.idservice = S.id)
    where S.idcompany = 42
    group by 1
    order by 2;
    Un explain de la requete sorti par mysql :

    table S : key idcompany, rows 108. using where temporary filesort.
    table E : key service.id, rows 439. using where.

    Ma requete met 28 secondes à s'exécuter, et ce à chaque fois, même le cache ne la garde pas.

    Est-ce que quelqu'un aurait une suggestion ? Des variables mysql à optimiser ? Les tables sont en innoDB.

    Merci infiniment !

  2. #2
    Modérateur
    Avatar de Chtulus
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2008
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2008
    Messages : 3 094
    Points : 8 678
    Points
    8 678
    Par défaut
    Bonsoir,

    Des variables mysql à optimiser ?
    En même temps on ne sait rien de tes tables...

    Je cherche tous les idteam uniques de la table employee dont l'idcompany est 42.
    DISTINCT est très bon pour les uniques...
    « Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions. »
    - Confucius -

    Les meilleurs cours, tutoriels et Docs sur les SGBD et le SQL
    Tous les cours Office
    Solutions d'Entreprise



  3. #3
    Membre averti Avatar de Tux++
    Étudiant
    Inscrit en
    Avril 2008
    Messages
    281
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2008
    Messages : 281
    Points : 379
    Points
    379
    Par défaut
    Je cherche tous les idteam uniques de la table employee dont l'idcompany est 42.
    Si j'ai bien compris, IDteam est un identifiant, il devrait donc être unique et ne pas avoir de doublons.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT E.idteam, min(E.sinceDate) as mini
    FROM employee E, service S
    WHERE E.idservice = S.id
    AND S.idcompany = 42
    ORDER BY mini
    devrait donc fonctionner correctement, mais sans infos suppl...
    Certified Oracle Advanced PL/SQL Professional
    Certified Oracle APEX Expert
    Certified Oracle SQL Expert

  4. #4
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 743
    Points
    11 743
    Par défaut
    Citation Envoyé par Tux++ Voir le message
    Si j'ai bien compris, IDteam est un identifiant, il devrait donc être unique et ne pas avoir de doublons.
    En toute logique, sur la table Employee, l'IDteam n'est pas unique puisqu'un équipe est composée de plusieurs employés.

    If_zen, tu n'as pas une table Team ?

    Citation Envoyé par Tux++ Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT E.idteam, min(E.sinceDate) as mini
    FROM employee E, service S
    WHERE E.idservice = S.id
    AND S.idcompany = 42
    ORDER BY mini
    devrait donc fonctionner correctement, mais sans infos suppl...
    Je suis d'accord avec toi sur le principe que la jointure externe ne sert à rien (un employé sans service n'est dans aucune société, donc pas dans la 42) et est sous-performante. Mais je préfèrerais l'écriture normalisée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT E.idteam, min(E.sinceDate)
    FROM employee E
      INNER JOIN service S ON E.idservice = S.id
    WHERE S.idcompany = 42
    GROUP BY 1
    ORDER BY 2;
    Antoun
    Expert Tableau, Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  5. #5
    Membre averti
    Avatar de if_zen
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2004
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2004
    Messages : 275
    Points : 316
    Points
    316
    Par défaut
    Bonjour à tous et merci pour vos précisions.

    Citation Envoyé par Antoun
    Je suis d'accord avec toi sur le principe que la jointure externe ne sert à rien (un employé sans service n'est dans aucune société, donc pas dans la 42) et est sous-performante.
    Bien vu, ça j'aurais pu y penser.

    Citation Envoyé par Antoun
    If_zen, tu n'as pas une table Team ?
    Je m'étais arrangé pour avoir des noms de table génériques pour que ça parle à tout le monde, mais je n'aurais peut-être pas du
    Dans mon cas, team correspondrait simplement à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    [team]
    - id
    - nom
    - adresse
    - ...
    Autre point, tous nos ID sont des bigint(20), j'ai cru lire que ça ne jouait pas en faveur des performances.
    D'un point de vue index, serait il judicieux de faire un index sur les sinceDate (DATE) ? A priori la clé utilisé par le requetteur serait de toute façons idService.


    Citation Envoyé par If_Zen
    table S : key idcompany, rows 108. using where temporary filesort.
    table E : key service.id, rows 439. using where.
    Cela vous semble-t-il correct ? Moi oui, mais je ne comprend pas les "28" secondes d'exécution du coup.


    Citation Envoyé par Chtulus
    DISTINCT est très bon pour les uniques...
    Mon but était de grouper les résultats par idTeam, donc ils se retrouvent forcément uniques.

    J'ai cru comprendre qu'il vous manquait des informations. C'est vrai que j'ai essayé de généraliser en donnant des noms usuels aux tables en essayant de ne garder que les informations nécessaires. S'il vous faut d'autres infos, n'hésitez pas à me demander !
    J'aurais aimé factoriser la requete pour en faire une plus simple et plus rapide. Merci à Tux++ et Antoun pour la correction sur la jointure !

    But de la requete : retrouver pour une company particulière, l'ensemble de ses team avec la date de participation la plus ancienne de ses employee.

Discussions similaires

  1. [MySQL] Comment optimiser cette requête ?
    Par AyManoVic dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 03/08/2010, 00h44
  2. Comment optimiser cette requête?
    Par Nympheasi dans le forum Requêtes
    Réponses: 10
    Dernier message: 05/10/2009, 03h51
  3. [SQL]Comment optimiser cette requete?
    Par neeux dans le forum Langage SQL
    Réponses: 2
    Dernier message: 31/12/2008, 08h21
  4. comment optimiser cette requete Postgres?
    Par medsine dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 29/05/2008, 14h19
  5. Listing / Comment optimiser cette base de donnée
    Par ds-network dans le forum Requêtes
    Réponses: 3
    Dernier message: 05/02/2007, 09h08

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