优化 MySQL 子查询

Optimize MySQL 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

我正在尝试制作这样的 table:

用户每位艺术家的播放次数

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

当然,我正在处理数十万行数据。我无法在 SO 上找到与此特定案例相关的任何内容,但任何 resources/instruction 将不胜感激。

谢谢!

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

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 更改为内部联接。

您的 table 中是否有索引?您可能需要 plays table 上的 artist_id 索引,如果您还没有的话。

此外,我假设 artist_id on 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@ 的查询。