2010-12-16 16 views
0

Ich kann nicht scheinen dies für das Leben von mir herauszufinden: xGROUP_CONCAT aus mehreren Unterabfragen?

Ich habe zwei Tabellen ..

  • 1 = Tag Links
  • 2 = Tag Data

Wenn ich nach einem Profil abfrage, kann jedes Profil mehrere Einträge in der Tag-Links-Tabelle haben. Sobald ich die Tag-Links abrufen, möchte ich den Tag-Text aus der Tag-Datentabelle abrufen.

Ich kann dies tun mit: SELECT * FROM platform.tagWords WHERE tagId IN (SELECT tagId FROM platform.user sProfilesTags WHERE userId = 1001)

Aber es geht durch jeden Tag (rund 50.000) und prüft dann, ob es den Benutzer zugeordnet wird, so dass nicht genau eine Lösung, da jede Abfrage 5- nimmt 8 Sekunden.

Gibt es eine Möglichkeit, dies umzukehren?

Alle Tipps oder Ratschläge werden sehr geschätzt.

Vielen Dank im Voraus!

* update

So versuche ich dies mit einem Join einen Stich zu geben, aber ich bin es zu stecken: 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

Sie erwähnen Profil, aber die Tabelle ist Tag Data? –

+0

Ja, die andere (Ursprungstabelle) ist usersProfiles, wo ich die userId finde, um die Tags zu finden, die aus der Tag-Links-Tabelle verlinkt sind. –

+0

Was ist das Tabellenschema (die 'CREATE' Anweisungen für die Tabellen)? Was ist mit dem Ergebnis der Join-Anweisung nicht das, was Sie wünschen? – outis

Antwort

-1

Ihre erste Abfrage sieht gut aus. Wenn es 5-8 Sekunden dauert, dann vermissen Sie wahrscheinlich einen Index auf usersProfilesTags(userId).

Der Versuch, dies in einer Abfrage zu tun ist schwieriger und wahrscheinlich langsamer als zwei separate Abfragen zu tun: eine Abfrage um das Profil zu erhalten, und eine weitere Abfrage, die Tags zu erhalten. Im Allgemeinen funktioniert MySQL am besten, wenn Sie mehrere einfache Abfragen statt einer großen, komplizierten Abfrage ausführen. Unterabfragen sind ein relativ neues Feature und funktionieren oft schlecht.

Beachten Sie auch, dass Sie eine GROUP BY für die GROUP_CONCAT() Abfrage fehlen. Sie müssten jede Spalte in userProfiles in der GROUP BY Liste auflisten.

+3

Das ist ein schlechter Rat. Versuchen Sie nicht, Abfragen in mehrere kleinere aufzuteilen, tun Sie das Gegenteil. Die Unterstützung von Unterabfragen wurde vor 8 Jahren hinzugefügt und hat kein angeborenes Leistungsproblem. Je mehr Abfragen Sie ausführen, je mehr Verbindungs- und Kommunikationsaufwand besteht, desto mehr Festplatten-E/A werden für das Abrufen von Zeilen verschwendet, die Sie nicht benötigen würden, wenn die Abfragen kombiniert würden, und je mehr Speicher zwischen den Programmen verloren geht hinauswerfen. –

+0

Ich habe viele Fälle gesehen, in denen MySQL eine temporäre Tabelle (ohne Indizes) für das Ergebnis der Unterabfrage erstellt, was zu einer langsamen Nested-Loops-Verknüpfung führt. In anderen Fällen führt es die äußere Abfrage mit der inneren Abfrage zusammen und führt die innere Abfrage für jede Zeile in der äußeren Abfrage aus. Lesen Sie das MySQL-Handbuch "Optimieren von Unterabfragen", um eine Vorstellung davon zu bekommen, wie begrenzt das Optimierungsprogramm für Unterabfragen ist. –

+0

Ich glaube, ich habe es :) SELECT GROUP_CONCAT (tags.tagWord SEPARATOR '') FROM (SELECT u.*, tagWords.tagWord VON platform.usersProfilesTags als u INNER JOIN platform.tagWords ON tagWords.tagId = u.tagId userid = 1001) als Tags –