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 :

Optimisation d'une requête


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27
    Par défaut Optimisation d'une requête
    Bonjour à tous,

    J'essaye d'optimiser la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    SELECT SQL_NO_CACHE DISTINCT(s.idspectacle),
     
    s.url_clean,s.idtypespectacle,s.creation_date,s.title as titlespectacle,
    sc.date as prochdate,
    ty.typespectacle,
    t.title as titletext, t.idtext as idtext, t.type as type, t.url_clean as url_clean_text,
    ct.idcontent, ct.title as titlecontent,
    cl.classification,om.idmultimedia, om.idrole, om.object 
     
    FROM 
     
    schedules sc,
    spectacles s,
    typesspectacles ty, 
    texts t,
    text_spectacle ts, 
    spectacle_person sp, 
    statscumul st, 
    object_multimedia om , 
    classification_module cm, 
    object_content oc, 
    classifications cl, 
    content_classification cc, 
    contents ct
     
    WHERE 
     
    sc.idspectacle=s.idspectacle
    AND ts.idtext=t.idtext
    AND s.idspectacle=ts.idspectacle
    AND sp.idspectacle=s.idspectacle
    AND s.idspectacle=oc.idobject
    AND ct.idcontent=oc.idcontent
    AND ct.idcontent=cc.idcontent
    AND st.idcontent=ct.idcontent
    AND st.idobject=s.idspectacle
    AND cl.idclassification=cc.idclassification
    AND cm.idclassification=cl.idclassification
    AND om.idobject=ct.idcontent
    AND om.object='contents'
    AND oc.object='spectacles'
    AND ct.language='fr'
    AND cm.module='thnet' 
    AND ct.display_media=1  
    AND ty.idtypespectacle=s.idtypespectacle
    AND st.type='article'
    AND st.video=1
    AND st.object='spectacles'  
     
    GROUP BY s.idspectacle
    ORDER BY st.count LIMIT 15
    Elle mets plus de 1,7 secondes à s'exécuter. Si j'enlève la table "schedules" ,qui fait 80 000 entrées (les autres font maximum 5000 entrées), je tombe déjà à 0.2 secondes

    Je me demandais si il fallait que j'ordonne mes jointures d'une certaines façon ? Utliser STRAIGHT_JOIN ?

    J'utilise le moteur InnoDB et les index semblent OK. j'ai maté avec EXPLAIN mais rien vu de probant... Les index sont OK.

    Merci d'avance pour vos idées !

  2. #2
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Saluton,
    MySQL préfère, et apparemment de loin, la syntaxe normalisée avec JOIN pour les jointures.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27
    Par défaut
    Merci pour ta réponse.

    j'ai du zapper un truc car j'ai reformulé ma requête et je suis maintenant à 13 secondes !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    SELECT SQL_NO_CACHE DISTINCT(s.idspectacle),
     
    s.url_clean,s.idtypespectacle,s.creation_date,s.title as titlespectacle,
    sc.date as prochdate,
    ty.typespectacle,
    t.title as titletext, t.idtext as idtext, t.type as type, t.url_clean as url_clean_text,ct.idcontent, ct.title as titlecontent,
    cl.classification,om.idmultimedia, om.idrole, om.object 
     
    FROM 
     
    (
    spectacles s 
     
    JOIN schedules sc ON sc.idspectacle=s.idspectacle
     
    JOIN spectacle_person sp ON sp.idspectacle=s.idspectacle
     
    JOIN typesspectacles ty ON ty.idtypespectacle=s. idtypespectacle
     
    JOIN (text_spectacle ts 
    		JOIN texts t ON ts.idtext=t.idtext)
    ON ts.idspectacle=s.idspectacle
     
    JOIN (object_content oc 
    		JOIN (contents ct
    				JOIN (content_classification cc
    					JOIN classifications cl 
    						ON cl.idclassification=cc.idclassification) 
    				ON ct.idcontent=cc.idcontent 
    				JOIN  object_multimedia om ON (om.idobject=ct.idcontent AND om.object='contents'))
    	ON oc.idcontent=ct.idcontent)
    ON oc.idobject=s.idspectacle
     
    JOIN statscumul st ON st.idobject=s.idspectacle
     
    )
     
    WHERE 
     
    st.type='article'
    AND st.video=1
    AND st.object='spectacles'
    AND ct.language='fr'
    AND ct.display_media=1
    AND oc.object='spectacles'
     
    GROUP BY s.idspectacle
    ORDER BY st.count LIMIT 15

  4. #4
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    En SQL, DISTINCT, lorsqu'il n'est pas utilisé au sein d'une fonction de regroupement (genre COUNT(DISTINCT Nomcolonne) ), gère l'unicité sur l'ensemble des colonnes de la ligne et non sur une colonne spécifique.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  5. #5
    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
    DISTINCT est un opérateur qui agit sur toutes les colonnes de la sélection donc les parenthèses autour de s.idspectacle sont inutiles. De plus, comme il y a un GROUP BY s.idspectacle, le DISTINCT me semble ici inutile.

    Au fait, pourquoi faire un GROUP BY alors qu'il n'y a pas de fonction de calcul dans votre requête ?

    Pour la clarté de la requête, il vaut mieux écrire les couples JOIN ON entiers au lieu de les imbriquer, comme le fait malheureusement Access.

    Les parenthèses entourant toutes les jointures sont inutiles.

    Voici votre requête remise en forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    SELECT SQL_NO_CACHE s.idspectacle, s.url_clean, s.idtypespectacle, s.creation_date, s.title AS titlespectacle,
      sc.date AS prochdate,
      ty.typespectacle,
      t.title AS titletext, t.idtext AS idtext, t.type AS type, t.url_clean AS url_clean_text,
      ct.idcontent, ct.title AS titlecontent,
      cl.classification,
      om.idmultimedia, om.idrole, om.object 
    FROM spectacles s 
    JOIN schedules sc ON sc.idspectacle = s.idspectacle
    JOIN spectacle_person sp ON sp.idspectacle = s.idspectacle
    JOIN typesspectacles ty ON ty.idtypespectacle = s.idtypespectacle
    JOIN text_spectacle ts ON ts.idspectacle = s.idspectacle
      JOIN texts t ON ts.idtext = t.idtext
    JOIN object_content oc ON oc.idobject = s.idspectacle
      JOIN contents ct ON oc.idcontent = ct.idcontent
        JOIN content_classification cc ON ct.idcontent = cc.idcontent
          JOIN classifications cl ON cl.idclassification = cc.idclassification     
        JOIN  object_multimedia om ON om.idobject = ct.idcontent AND om.object = 'contents' 
    JOIN statscumul st ON st.idobject = s.idspectacle
    WHERE st.type = 'article'
      AND st.video = 1
      AND st.object = 'spectacles'
      AND ct.LANGUAGE = 'fr'
      AND ct.display_media = 1
      AND oc.object = 'spectacles'
    ORDER BY st.count 
    LIMIT 15
    Si vous nous dites plus précisément ce que vous cherchez à obtenir comme résultat, il sera plus facile de vous aider.
    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 !

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27
    Par défaut
    Merci pour ces explications, la difficulté vient bien de mes tentatives de regroupement.

    En supprimant DISTINCT et GROUP BY, ma requête de base s'exécute en 0.1 sec. et la requête réécrite proprement avec l'instruction JOIN également en 0.1 sec.

    Quelques centièmes, sur mes données de test, en faveur de la requête réécrite. Je vais donc essayer de m'y mettre mais les mauvaises habitudes ont la vie dure

    Ceci étant, il me manque donc le regroupement sur la colonne s.idspectacle. (pas de spectacles en doublons)

    Faut-il que je l'envisage du côté du langage qui traite les résultats ?

  7. #7
    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
    Citation Envoyé par YvesTan Voir le message
    Ceci étant, il me manque donc le regroupement sur la colonne s.idspectacle. (pas de spectacles en doublons)

    Faut-il que je l'envisage du côté du langage qui traite les résultats ?
    Bis repetita :
    Si vous nous dites plus précisément ce que vous cherchez à obtenir comme résultat, il sera plus facile de vous aider.
    Parce que là je vois une requête qui ramène des données de presque toutes les tables concernées par ladite requête. Avec une seule ligne pour s.idspectacle, il va falloir déterminer comment sont choisies les lignes des tables en jointure. Et ça on ne peut pas le deviner !
    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 !

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

Discussions similaires

  1. Optimisation d'une requête
    Par Louis-Guillaume Morand dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 20/12/2005, 18h21
  2. Optimisation d'une requête d'insertion
    Par fdraven dans le forum Oracle
    Réponses: 15
    Dernier message: 01/12/2005, 14h00
  3. Optimisation d'une requête patchwork
    Par ARRG dans le forum Langage SQL
    Réponses: 1
    Dernier message: 11/09/2005, 15h23
  4. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45
  5. [DB2] Optimisation d'une requête
    Par ahoyeau dans le forum DB2
    Réponses: 7
    Dernier message: 11/03/2005, 17h54

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