2016-08-12 2 views
1

Gibt es eine Möglichkeit, die folgende SQL optimiert, so dass es schneller laufen würde?Optimieren Sie GROUP_CONCAT in SQL auf MySQL

SELECT bitValue as bitV, endName as endN, filDuration as filD, filSize as filS, genName as genN, sonAdditionalPrefix AS sonAP, sonDate as sonD, sonID, sonIsRip, sonName, typName, sonPlays as plays, 
(SELECT GROUP_CONCAT(a.artName SEPARATOR ';') FROM tblArtists a, tblSoAr sa WHERE a.artID = sa.soarartIDRef AND sa.soarsonIDRef = s.sonID) as artists, 
(SELECT GROUP_CONCAT(a.artName SEPARATOR ';') FROM tblArtists a, tblRemixer r WHERE a.artID = r.remartIDRef AND r.remsonIDRef = s.sonID) as remixer, 
(SELECT GROUP_CONCAT(a.artName SEPARATOR ';') FROM tblArtists a, tblFeaturing f WHERE a.artID = f.feaartIDRef AND f.feasonIDRef = s.sonID) as featuring, 
(SELECT GROUP_CONCAT(ta.tagName SEPARATOR ';') FROM tblTags ta, tblSoTa st WHERE ta.tagID = st.sotatagIDRef AND st.sotasonIDRef = s.sonID) as tags 
FROM tblSongs s, tblFiles f, tblGenres g, tblEndings e, tblBitrates b, tblTypes t 
WHERE s.sonfilIDRef = f.filID AND s.songenIDRef = g.genID AND f.filendIDRef = e.endID AND f.filbitIDRef = b.bitID AND s.sontypIDRef = t.typID AND sonshaIDRef = 1 AND sonWasEdited = 1 AND sonDeleted = 0 AND sonOnWishlist = 0 ; 

ich den Engpass aufgetreten sind die GROUP_CONCAT der aber ich konnte durch die Verwendung eines alternativen oder die Optimierung der Abfrage nicht einen Weg finden, damit es schneller laufen würde. Im Moment benötigt die Abfrage etwa 3.2s auf 2700 Einträge (mysql-Datenbank 5.1.73, mysqli). Alle Tabellen haben Indizes in den wichtigen Spalten.

So nach etwas LEFT Umsetzung JOINS meine Abfrage folgt aussieht:

SELECT bitValue as bitV, endName as endN, filDuration as filD, filSize as filS, genName as genN, sonAdditionalPrefix AS sonAP, sonDate as sonD, sonID, sonIsRip, sonName, typName, sonPlays as plays,  
conArtists.artists, conRemixer.remixer, conFeaturing.featuring, conTags.tags 
FROM (tblSongs s, tblFiles f, tblGenres g, tblEndings e, tblBitrates b, tblTypes t) 
LEFT JOIN (SELECT tblSoAr.soarsonIDRef as soarsonIDRef, GROUP_CONCAT(tblArtists.artName SEPARATOR ';') as artists FROM tblSoAr, tblArtists WHERE tblArtists.artID = tblSoAr.soarartIDRef GROUP BY soarsonIDRef) AS conArtists ON conArtists.soarsonIDRef = s.sonID 
LEFT JOIN (SELECT tblRemixer.remsonIDRef as remsonIDRef, GROUP_CONCAT(tblArtists.artName SEPARATOR ';') as remixer FROM tblRemixer, tblArtists WHERE tblArtists.artID = tblRemixer.remsonIDRef GROUP BY remsonIDRef) AS conRemixer ON conRemixer.remsonIDRef = s.sonID 
LEFT JOIN (SELECT tblFeaturing.feasonIDRef as feasonIDRef, GROUP_CONCAT(tblArtists.artName SEPARATOR ';') as featuring FROM tblFeaturing, tblArtists WHERE tblArtists.artID = tblFeaturing.feasonIDRef GROUP BY feasonIDRef) AS conFeaturing ON conFeaturing.feasonIDRef = s.sonID 
LEFT JOIN (SELECT tblSoTa.sotasonIDRef as sotasonIDRef, GROUP_CONCAT(tblTags.tagName SEPARATOR ';') as tags FROM tblSoTa, tblTags WHERE tblTags.tagID = tblSoTa.sotasonIDRef GROUP BY sotasonIDRef) AS conTags ON conTags.sotasonIDRef = s.sonID 
WHERE s.sonfilIDRef = f.filID AND s.songenIDRef = g.genID AND f.filendIDRef = e.endID AND f.filbitIDRef = b.bitID AND s.sontypIDRef = t.typID AND sonshaIDRef = 1 AND sonWasEdited = 1 AND sonDeleted = 0 AND sonOnWishlist = 0; 
+0

In grober Näherung gibt es in SQL kein Problem, für das GROUP_CONCAT einen Teil der Lösung bilden muss. Also, da ist deine Optimierung genau da! – Strawberry

+1

Lernen Sie, die richtige explizite 'JOIN'-Syntax zu verwenden. –

Antwort

1

Ich glaube, Sie die Subqueries vermeiden können (die für jede Zeile durchgeführt werden), indem zuerst die artName Werte gruppieren und sie dann Beitritt:

alt query:

:

select 
a.id, 
(select group_concat(x) as x_concat from table_2 as _b where a.id = _b.id and ...) as b, 
(select group_concat(x) as x_concat from table_3 as _c where a.id = _b.id and ...) as c 
from table_1 as a 
where ... 

dies etwas sein sollte

select 
a.id, 
b.x_concat, 
c.x_concat 
from 
table_1 as a, 
left join (select id, group_concat(x) as x_concat from table_2 where ... group by id) as b on a.id = b.id, 
left join (select id, group_concat(x) as x_concat from table_3 where ... group by id) as c on a.id = c.id 
where ... 
+0

Danke für diesen Hinweis, also braucht die Abfrage jetzt 2,5s, ich denke, es gibt keinen Platz mehr für weitere Verbesserungen. – Vetterjack