繁体   English   中英

在 MySQL 上优化 SQL 中的 GROUP_CONCAT

[英]Optimize GROUP_CONCAT in SQL on MySQL

有没有办法优化以下 SQL,使其运行得更快?

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 JOINS 之后,我的查询如下所示:

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;

我认为您可以通过首先对 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 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM