优化MySQL子查询

时间:2015-06-17 18:16:51

标签: mysql optimization subquery

我是MySQL的新手,我正试图简化这句话:

SELECT DISTINCT p.user_id, a.artist_id, a.artist_name, 
(SELECT COUNT(*) FROM plays WHERE user_id = p.user_id AND artist_id = a.artist_id) as count
FROM plays as p
LEFT OUTER JOIN artists AS a
ON p.artist_id = a.artist_id;

这完成了我的需要但是痛苦地慢慢地。必须有一些方法以更有效的方式做到这一点。为了让您了解架构:

艺术家

artist_id   artist_name
1           ArtistA
2           ArtistB
3           ArtistC
4           ArtistD

起着

user_id     artist_id 
1           1
1           2
1           2
2           4
2           4
3           3

我试图制作这样一张桌子:

按用户播放每位艺术家

user_id    artist_id    artist_name    count
1          1            ArtistA        1
1          2            ArtistB        2
2          4            ArtistD        2
4          3            ArtistC        1

当然,我正在处理数十万行数据。我无法在这个特定情况下找到关于SO的任何内容,但任何资源/指令都会受到极大的赞赏。

谢谢!

2 个答案:

答案 0 :(得分:0)

是的,它被称为简单聚合:

SELECT p.user_id, a.artist_id, a.artist_name, COUNT(*) as cnt
FROM artists a JOIN
     plays p
     ON p.artist_id = a.artist_id
GROUP BY p.user_id, a.artist_id, a.artist_name;

因为您的聚合具有来自两个表的字段,所以您似乎确实希望两个表之间匹配。我将LEFT JOIN更改为内连接。

答案 1 :(得分:0)

你的桌子上有索引吗?如果您还没有,artist_id表上的plays可能需要索引。

此外,我假设artist_id artists如果是主键,但如果没有,您也会想要这样做。

有关详细信息,请参阅https://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

提供DESC SELECT DISTINCT p.user_id, a.artist_id, a.artist_name, (SELECT COUNT(*) FROM plays WHERE user_id = p.user_id AND artist_id = a.artist_id) as count FROM plays as p LEFT OUTER JOIN artists AS a ON p.artist_id = a.artist_id;的输出以检查您的查询是否使用索引可能会有所帮助。

话虽如此,你也应该切换到gordon-linoff @的查询。