2010-12-16 3 views
0

Je ne peux pas sembler figurer cela pour la vie de moi: xGROUP_CONCAT à partir de plusieurs sous-requêtes?

J'ai deux tables ..

  • 1 = Tag Liens
  • 2 = Tag données

Lorsque je demande un profil, chaque profil peut avoir plusieurs entrées dans la table des liens de balises. Une fois que j'ai récupéré les liens d'étiquette, je veux obtenir le texte d'étiquette de la table de données d'étiquette.

Je peux le faire avec: SELECT * FROM platform.tagWords WHERE tagId IN (SELECT tagId FROM platform.user sProfilesTags WHERE userId = 1001)

Mais il passe par chaque balise (environ 50 000), puis vérifie si elle est affectée à l'utilisateur de sorte que n'est pas exactement une solution que chaque requête prend 5 8 secondes

Y a-t-il un moyen d'inverser cela?

Des conseils ou astuces seront très appréciés.

Merci d'avance!

* Mise à jour

Je suis en train de donner un coup de couteau ce avec une jointure, mais je suis coincé là-bas aussi: P

SELECT                   

    GROUP_CONCAT(tagWords.tagWord SEPARATOR ', ') AS tags,       
    usersProfiles.*                 

FROM platform.users u               

INNER JOIN platform.usersProfilesTags ON usersProfilesTags.userId = u.userId 
INNER JOIN platform.usersProfiles ON usersProfiles.userId = u.userId   
INNER JOIN platform.tagWords ON tagWords.tagId = usersProfilesTags.tagId  

WHERE u.userName = 'mattstest' 
+0

Vous mentionnez le profil, mais le tableau est Tag Data? –

+0

Oui, l'autre (table d'origine) est usersProfiles où j'obtiens l'ID utilisateur pour trouver les balises qui sont liées à partir de la table des liens d'étiquette. –

+0

Quel est le schéma de la table (les instructions 'CREATE' pour les tables)? Qu'en est-il du résultat de la déclaration de jointure n'est pas ce que vous désirez? – outis

Répondre

-1

Votre première requête semble bien. Si cela prend 5-8 secondes, il vous manque probablement un index sur usersProfilesTags(userId).

Il est plus difficile et probablement plus lent d'effectuer cette opération dans une requête que de faire deux requêtes distinctes: une requête pour obtenir le profil et une autre requête pour obtenir les balises. Généralement, MySQL fonctionne mieux lorsque vous exécutez plusieurs requêtes simples plutôt qu'une grande requête compliquée. Les sous-requêtes sont une fonctionnalité relativement récente et fonctionnent souvent mal.

Notez également qu'il vous manque un GROUP BY pour la requête GROUP_CONCAT(). Vous devez répertorier chaque colonne dans userProfiles dans la liste GROUP BY.

+3

Ceci est un mauvais conseil. N'essayez pas de diviser les requêtes en plusieurs plus petites, faites le contraire. Le support des sous-requêtes a été ajouté il y a 8 ans et n'a aucun problème de performance innée. Plus vous générez de requêtes, plus vous augmentez les coûts de connexion et de communication, plus vous perdez d'IO sur le disque en récupérant des lignes dont vous n'auriez pas besoin si les requêtes sont combinées et plus vous gaspillez de mémoire entre les programmes que vous allez jeter. –

+0

J'ai vu de nombreux cas où MySQL crée une table temporaire (sans index) pour le résultat de la sous-requête, ce qui entraîne une lente jointure de boucles imbriquées. D'autres fois, il fusionne mal la requête externe avec la requête interne et exécute la requête interne pour chaque ligne de la requête externe. Lisez la section "Optimisation des sous-requêtes" du manuel MySQL pour avoir une idée de la limite de l'optimiseur pour les sous-requêtes. –

+0

Je pense que je l'ai :) SELECT GROUP_CONCAT (tags.tagWord SEPARATOR ',') FROM (SELECT u.*, tagWords.tagWord DE platform.usersProfilesTags comme u INNER JOIN platform.tagWords SUR tagWords.tagId = u.tagId OÙ userId = 1001) en tant que balises –

Questions connexes