2016-08-12 4 views
1

次のSQLを最適化してより高速に実行できる方法はありますか?MySQLのSQLでGROUP_CONCATを最適化する

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 ; 

私がボトルネックに遭遇したがGROUP_CONCATのですが、それはより速く実行しますので、私が代わりに使用したり、クエリを最適化することによって、方法を見つけることができませんでした。 現在、2700エントリ(mysqlデータベース5.1.73、mysqli)で約3.2秒のクエリが必要です。すべてのテーブルには、重要な列にインデックスが設定されています。だから、

いくつかのLEFTを実装する私のクエリは次のように見える参加した後:

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

大雑把に言えば、GROUP_CONCATがソリューションの一部を構成する必要があるSQLに問題はありません。だから、そこにあなたの最適化があります! – Strawberry

+1

適切な明示的な 'JOIN'構文を使用する方法を学んでください。 –

答えて

1

私はあなたが最初artName値をグループ化し、それらを結合して(行ごとに行われます)サブクエリを避けることができると思う:

古いクエリ:

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 ... 

はこのようなものであるべき

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

そのヒントのおかげで、クエリに2.5秒が必要になりました。私はさらなる改善の余地がないと思います。 – Vetterjack