【发布时间】:2017-01-05 22:43:11
【问题描述】:
我有这样的 MySQL 表,我想计算每种类型的 TOP10:
- rankings_2016(trackId、genreId、排名、时间戳)
- 流派(流派 ID、流派名称)
- 曲目(trackId、trackName、genreId)
- 艺术家(artistId,artistName)
- artists_tracks (artistId, trackId)
我想获得每个流派、每个曲目和每个艺术家的 TOP10 排名。
一首曲目或一位艺术家最多可以有 2 个流派。排名可能相同。只是为了了解 LIMIT 2:
genreId | trackId | ranking
---------------------------------
0 1111 100
0 2222 99
1 1111 100
1 2222 99
genreId | artistId | ranking
---------------------------------
0 1111 100
0 2222 99
1 1111 100
1 2222 99
我找到的唯一解决方案是将所有内容都放在一个表中,然后在页面中设置 LIMIT 10,但它在大小方面会扼杀我的数据库(我的资源有限)。
对于我写的这些曲目:
SELECT trackId, genreId, @newRank := SUM(ranking) as ranking
FROM rankings_2016
WHERE timestamp >= ( select unix_timestamp('2016-01-01') )
AND timestamp <= ( select unix_timestamp('2016-12-31') )
GROUP BY trackId, genreId
对于艺术家:
SELECT artistId, genreId, @newRank := SUM(a1.ranking) as ranking
FROM rankings_2016 a1
LEFT JOIN artists_tracks a2
ON a1.trackId = a2.trackId
WHERE timestamp >= ( select unix_timestamp('2016-01-01') )
AND timestamp <= ( select unix_timestamp('2016-12-31') )
GROUP BY artistId, genreId
提前感谢大家的提示。
更新
一般的逻辑(和接受的回复)需要良好的索引和高性能的服务器。
除非我增加 CPU,否则我的 ARTISTS 会因错误 500 而失败。 一般来说,用 INNER 替换 LEFT 可以节省 1 秒。
【问题讨论】:
-
如果性能是一个问题并且排名不经常变化,请考虑预先计算答案。
-
排名每天都在变化:我的实际查询预先填充了一些表,所有结果每天浪费数十万行。如何在预填充阶段直接限制为 20 个?
-
确保您在
timestamp表上有一个索引。想不出还有什么可能会减慢这些简单查询的速度。 -
性能还可以,大小是 KO:我想获得每个流派、每个曲目和每个艺术家的 TOP10 排名。谢谢
-
也许这已经解决了,但如果你还在苦苦挣扎,请参阅meta.stackoverflow.com/questions/333952/…
标签: mysql group-by limit database-performance