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 :

Optimisations et autres galères !


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 3
    Par défaut Optimisations et autres galères !
    Bonsoir à tous.
    J'ai un bdd de 3M d'entrée. Elle possède 4 tables :

    - videos (contenant des id de thumbs)
    - link_tags (contenant des id de videos et de tag)
    - tags (contenant des tags)
    - thumbs (contenant des id videos et adresse de thumbs)

    Je crois que ça doit déjà vous dire quelques chose. Je souhaite faire une recherche de vidéos selon des tags donnés dans ma requête SQL. Voici la requête que j'exécute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT v.*
    FROM videos v 
    INNER JOIN (
                SELECT lt.ID_VIDEO
                FROM link_tags lt 
                   INNER JOIN videos v ON v.id = lt.ID_VIDEO
                   INNER JOIN tags t ON t.ID = lt.ID_TAG 
                WHERE t.tag IN ('TAGS', 'TAGS')
    ) 
    GROUP BY lt.ID_VIDEO HAVING Count(lt.ID_VIDEO) = *nbrTags*) vv ON v.ID = vv.ID_VIDEO
    Elle me semble correcte mais lourde tout de même, ça se vérifie, une requête prend 5 secondes sur un serveur dédié Linux 64bits 4Core 2.67Ghz et 16go de ram. Le query_cache_size est à 128M.
    Le problème c'est que mes capacités en mysql ne me permettent pas une optimisation plus efficace ... Vous auriez des idées ? Peut être une nouvelle organisation de la bdd ? Si oui, comment faire autrement ?

    Je vous remercies par avance !

  2. #2
    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 Misterweb34 Voir le message
    Bonsoir à tous.
    J'ai un bdd de 3M d'entrée. Elle possède 4 tables :

    - videos (contenant des id de thumbs)
    - link_tags (contenant des id de videos et de tag)
    - tags (contenant des tags)
    - thumbs (contenant des id videos et adresse de thumbs)

    Je crois que ça doit déjà vous dire quelques chose. Je souhaite faire une recherche de vidéos selon des tags donnés dans ma requête SQL.
    Voici la requête que j'exécute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT v.*
    FROM videos v 
    INNER JOIN (
                SELECT lt.ID_VIDEO
                FROM link_tags lt 
                   INNER JOIN videos v ON v.id = lt.ID_VIDEO
                   INNER JOIN tags t ON t.ID = lt.ID_TAG 
                WHERE t.tag IN ('TAGS', 'TAGS')
    ) 
    GROUP BY lt.ID_VIDEO HAVING Count(lt.ID_VIDEO) = *nbrTags*) vv ON v.ID = vv.ID_VIDEO
    Elle me semble correcte
    Non ! Tu as mis la condition de jointure dans le HAVING !

    C'est plutôt ça ta requête non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT v.-- les colonnes nécessaires et pas étoile !
    FROM videos v 
    INNER JOIN 
    (
    	SELECT lt.ID_VIDEO
    	FROM link_tags lt 
    	INNER JOIN videos v ON v.id = lt.ID_VIDEO
    	INNER JOIN tags t ON t.ID = lt.ID_TAG 
    	WHERE t.tag IN ('TAGS', 'TAGS') -- 2 fois la même valeur ! Pourquoi ?
    	GROUP BY lt.ID_VIDEO 
    	HAVING Count(lt.ID_VIDEO) = *nbrTags*
    ) vv ON v.ID = vv.ID_VIDEO
    mais lourde tout de même, ça se vérifie, une requête prend 5 secondes sur un serveur dédié Linux 64bits 4Core 2.67Ghz et 16go de ram. Le query_cache_size est à 128M.
    Première chose à vérifier quand on constate des requêtes lentes : les index !
    Ici, il faut que link_tags.ID_VIDEO et link_tags.ID_TAG soient indexés, ce qui devrait naturellement être le cas puisque ce sont des clés étrangères.

    Donne nous la composition de tes tables (résultats des requêtes SHOW CREATE TABLE nom_de_la_table).
    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 !

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 3
    Par défaut
    Effectivement il y avait un soucis dans les index. Un seul index s'occupait de deux colonnes...

    Il y a maintenant un index par colonne dites de "grandes utilisations". Voici mes structures de tables actuelles :

    link_tags :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE `link_tags` (
     `ID` int(11) NOT NULL AUTO_INCREMENT,
     `ID_VIDEO` int(11) NOT NULL,
     `ID_TAG` int(11) NOT NULL,
     PRIMARY KEY (`ID`),
     KEY `ID_TAG` (`ID_TAG`),
     KEY `ID_VIDEO` (`ID_VIDEO`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3337626 DEFAULT CHARSET=latin1
    tags :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	CREATE TABLE `tags` (
     `ID` int(11) NOT NULL AUTO_INCREMENT,
     `TAG` varchar(25) NOT NULL,
     `VIEW` int(11) NOT NULL,
     PRIMARY KEY (`ID`),
     KEY `TAG` (`TAG`)
    ) ENGINE=InnoDB AUTO_INCREMENT=100044 DEFAULT CHARSET=latin1
    videos :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE TABLE `videos` (
     `ID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
     `ID_VIDEO` mediumint(9) NOT NULL,
     `URL` text NOT NULL,
     `TITLE` text NOT NULL,
     `DURATION` int(11) NOT NULL,
     `DATE_LOCAL` bigint(20) NOT NULL,
     `DATE_VIDEO` bigint(20) NOT NULL,
     `VIDEO_FROM` int(11) NOT NULL,
     `VIEW` int(11) NOT NULL,
     PRIMARY KEY (`ID`),
     UNIQUE KEY `ID_VIDEO` (`ID_VIDEO`),
     KEY `VIDEO_FROM` (`VIDEO_FROM`)
    ) ENGINE=InnoDB AUTO_INCREMENT=524556 DEFAULT CHARSET=latin1
    Et oui, c'est vrai, la requête que j'avais tapé n'était pas bonne. Mais celle que j’exécute correspond bien à celle que tu as fait. Je suis maintenant à 0.9s pour 3 tags, 0.5s pour deux, 0.4 pour une. C'est pas encore ça :/

    Selon des personnes autours de moi, il vaudrait mieux que j'utilise les INTERSECT... ?

    Edit : On vient également de me dire de posser à PostGreSql, il y a t'il un avantage certains pour ce genre d'application ?

  4. #4
    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
    J'ai un bdd de 3M d'entrée.

    Je suis maintenant à 0.9s pour 3 tags, 0.5s pour deux, 0.4 pour une. C'est pas encore ça :/
    Je trouve ça pas si mal ! Ça dépend aussi du matériel qui héberge la BDD et du logiciel qui y accède.
    Tu obtiens ces temps directement en ligne de commande sur le serveur MySQL ou via un logiciel ?

    Selon des personnes autours de moi, il vaudrait mieux que j'utilise les INTERSECT... ?
    Sauf que ce mauvais MySQL ne connait pas INTERSECT !

    Que cherches-tu à faire exactement ?
    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 !

Discussions similaires

  1. Des boutons qui ne fonctionnent pas & autres galères !
    Par apierart dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 28/08/2013, 18h10
  2. Réponses: 2
    Dernier message: 09/01/2008, 10h56
  3. [XSLT]for-each imbriqués, et autres galères...
    Par Sarrus dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 16/03/2006, 17h57
  4. Entre autre : frustum de vue, optimisations...
    Par MaxPayne dans le forum OpenGL
    Réponses: 8
    Dernier message: 18/03/2005, 22h42

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