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

Requêtes MySQL Discussion :

Analyse EXPLAIN entre deux requêtes similaires


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 16
    Points : 15
    Points
    15
    Par défaut Analyse EXPLAIN entre deux requêtes similaires
    Bonjour,

    Je modifie actuellement un site pour le rendre plus "propre",

    j'ai modifié une requête SQL de la forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT al.titre, al.image_lien, al.titre_url, ar.nom_url 
    FROM ms_album al, ms_artiste ar 
    WHERE al.id_artiste1 =13 AND ar.id =13 AND ( TO_DAYS( NOW( ) ) - TO_DAYS( date_sortie ) <=3 ) 
    ORDER BY al.coeff_actu DESC , al.reference DESC LIMIT 5
    dont le résultat de explain me donne :
    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE ar const PRIMARY PRIMARY 4 const 1 Using filesort
    1 SIMPLE al ref index_id_artiste1 index_id_artiste1 4 const 20 Using where
    par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    EXPLAIN SELECT al.titre, al.image_lien, al.titre_url, ar.nom_url 
    FROM ms_album al 
    LEFT JOIN ms_artiste ar ON ar.id = al.id_artiste1 
    WHERE al.id_artiste1 =13 
    AND (TO_DAYS(NOW()) - TO_DAYS(date_sortie) <= 3) 
    ORDER BY al.coeff_actu DESC, al.reference DESC LIMIT 5
    dont explain me donne :

    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE al ref index_id_artiste1 index_id_artiste1 4 const 20 Using where; Using filesort
    1 SIMPLE ar const PRIMARY PRIMARY 4 const 1
    La deuxième requête semble plus rapide, mais j'ai du mal à analyser la différence entre les deux EXPLAIN, puisque les clés utilisées sont les mêmes et les extra aussi ; seul l'ordre change.
    Selon vous, quelle requête faut-il privilégier ?

  2. #2
    Membre habitué

    Profil pro
    Inscrit en
    Février 2009
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2009
    Messages : 129
    Points : 159
    Points
    159
    Par défaut
    Bonjour,

    L'ordre de jointure change dans la deuxième requête parce que tu as mis un LEFT JOIN : dans ce cas l'optimiseur choisit toujours de joindre les tables dans l'ordre d'écriture. Ici, il serait plus logique de mettre un INNER JOIN.

    Une chose que tu peux peut-être faire aussi, c'est remplacer NOW() par sa valeur calculée dans le langage de programmation de ton application. Ca permettra à la requête d'être mise dans le cache de requête. D'ailleurs, comme tu utilises TO_DAYS(), il serait plus logique de calculer la valeur de CURRENT_DATE() plutôt que NOW().

    Tu peux aussi simplifier un peu ton expression sur les dates en supprimant un appel à TO_DAYS() de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    date_sortie >= '2010-04-23' - INTERVAL 3 DAY
    Après, si tu peux indiquer la structure de tes tables, il y a peut-être moyen de voir si on peut travailler sur les index.

    Stéphane

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 036
    Points
    34 036
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par StephaneC. Voir le message
    L'ordre de jointure change dans la deuxième requête parce que tu as mis un LEFT JOIN : dans ce cas l'optimiseur choisit toujours de joindre les tables dans l'ordre d'écriture. Ici, il serait plus logique de mettre un INNER JOIN.
    Je dirais même plus !
    Les deux requêtes en sont pas équivalentes puisque la première fait implicitement une jointure interne alors que la seconde fait une jointure externe !
    Il FAUT mettre un INNER JOIN dans la nouvelle requête !

    Sinon je plussoie l'utilisation de CURRENT_DATE et de INTERVAL.
    Se méfier toutefois des opérations arithmétiques sur les dates avec MySQL ! Il existe des fonctions spéciales pour ça :
    DATE_ADD et DATE_SUB
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

Discussions similaires

  1. problème de jointure entre deux requêtes séparées
    Par sinifer dans le forum Requêtes
    Réponses: 2
    Dernier message: 28/05/2009, 15h24
  2. Différence entre deux "requêtes"
    Par zaventem dans le forum Développement
    Réponses: 3
    Dernier message: 16/03/2009, 12h01
  3. [Requête]Problèmes de nombre d'enregistrements entre deux requêtes
    Par Paul Gasser dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 23/03/2007, 12h20
  4. Addition entre deux requêtes
    Par tazmania dans le forum Langage SQL
    Réponses: 4
    Dernier message: 17/10/2006, 17h17
  5. Différence entre deux requêtes
    Par viny dans le forum Langage SQL
    Réponses: 7
    Dernier message: 03/10/2006, 16h28

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