fix: speedup top-artists and top-albums queries (#167)

This commit is contained in:
Gabe Farrell 2026-01-21 17:30:59 -05:00 committed by GitHub
parent c59c6c3baa
commit 16cee8cfca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 112 additions and 128 deletions

View file

@ -48,12 +48,12 @@ WHERE r.title = ANY ($1::TEXT[])
-- name: GetTopReleasesFromArtist :many -- name: GetTopReleasesFromArtist :many
SELECT SELECT
x.*, x.*,
get_artists_for_release(x.id) AS artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM ( FROM (
SELECT SELECT
r.*, r.*,
COUNT(*) AS listen_count, COUNT(*) AS listen_count
get_artists_for_release(r.id) AS artists
FROM listens l FROM listens l
JOIN tracks t ON l.track_id = t.id JOIN tracks t ON l.track_id = t.id
JOIN releases_with_title r ON t.release_id = r.id JOIN releases_with_title r ON t.release_id = r.id
@ -68,12 +68,12 @@ LIMIT $3 OFFSET $4;
-- name: GetTopReleasesPaginated :many -- name: GetTopReleasesPaginated :many
SELECT SELECT
x.*, x.*,
get_artists_for_release(x.id) AS artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM ( FROM (
SELECT SELECT
r.*, r.*,
COUNT(*) AS listen_count, COUNT(*) AS listen_count
get_artists_for_release(r.id) AS artists
FROM listens l FROM listens l
JOIN tracks t ON l.track_id = t.id JOIN tracks t ON l.track_id = t.id
JOIN releases_with_title r ON t.release_id = r.id JOIN releases_with_title r ON t.release_id = r.id

View file

@ -39,90 +39,82 @@ HAVING COUNT(DISTINCT at.artist_id) = cardinality($3::int[]);
-- name: GetTopTracksPaginated :many -- name: GetTopTracksPaginated :many
SELECT SELECT
x.id, x.track_id AS id,
x.title,
x.musicbrainz_id,
x.release_id,
x.image,
x.listen_count,
x.artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM (
SELECT
t.id,
t.title, t.title,
t.musicbrainz_id, t.musicbrainz_id,
t.release_id, t.release_id,
r.image, r.image,
x.listen_count,
get_artists_for_track(x.track_id) AS artists,
x.rank
FROM (
SELECT
track_id,
COUNT(*) AS listen_count, COUNT(*) AS listen_count,
get_artists_for_track(t.id) AS artists RANK() OVER (ORDER BY COUNT(*) DESC) as rank
FROM listens l FROM listens
JOIN tracks_with_title t ON l.track_id = t.id WHERE listened_at BETWEEN $1 AND $2
JOIN releases r ON t.release_id = r.id GROUP BY track_id
WHERE l.listened_at BETWEEN $1 AND $2 ORDER BY listen_count DESC
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image LIMIT $3 OFFSET $4
) x ) x
ORDER BY x.listen_count DESC, x.id JOIN tracks_with_title t ON x.track_id = t.id
LIMIT $3 OFFSET $4; JOIN releases r ON t.release_id = r.id
ORDER BY x.listen_count DESC, x.track_id;
-- name: GetTopTracksByArtistPaginated :many -- name: GetTopTracksByArtistPaginated :many
SELECT SELECT
x.id, x.track_id AS id,
x.title,
x.musicbrainz_id,
x.release_id,
x.image,
x.listen_count,
x.artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM (
SELECT
t.id,
t.title, t.title,
t.musicbrainz_id, t.musicbrainz_id,
t.release_id, t.release_id,
r.image, r.image,
x.listen_count,
get_artists_for_track(x.track_id) AS artists,
x.rank
FROM (
SELECT
l.track_id,
COUNT(*) AS listen_count, COUNT(*) AS listen_count,
get_artists_for_track(t.id) AS artists RANK() OVER (ORDER BY COUNT(*) DESC) as rank
FROM listens l FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id JOIN artist_tracks at ON l.track_id = at.track_id
JOIN releases r ON t.release_id = r.id
JOIN artist_tracks at ON at.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2 WHERE l.listened_at BETWEEN $1 AND $2
AND at.artist_id = $5 AND at.artist_id = $5
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image GROUP BY l.track_id
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4
) x ) x
ORDER BY x.listen_count DESC, x.id JOIN tracks_with_title t ON x.track_id = t.id
LIMIT $3 OFFSET $4; JOIN releases r ON t.release_id = r.id
ORDER BY x.listen_count DESC, x.track_id;
-- name: GetTopTracksInReleasePaginated :many -- name: GetTopTracksInReleasePaginated :many
SELECT SELECT
x.id, x.track_id AS id,
x.title,
x.musicbrainz_id,
x.release_id,
x.image,
x.listen_count,
x.artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM (
SELECT
t.id,
t.title, t.title,
t.musicbrainz_id, t.musicbrainz_id,
t.release_id, t.release_id,
r.image, r.image,
x.listen_count,
get_artists_for_track(x.track_id) AS artists,
x.rank
FROM (
SELECT
l.track_id,
COUNT(*) AS listen_count, COUNT(*) AS listen_count,
get_artists_for_track(t.id) AS artists RANK() OVER (ORDER BY COUNT(*) DESC) as rank
FROM listens l FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id JOIN tracks t ON l.track_id = t.id
JOIN releases r ON t.release_id = r.id
WHERE l.listened_at BETWEEN $1 AND $2 WHERE l.listened_at BETWEEN $1 AND $2
AND t.release_id = $5 AND t.release_id = $5
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image GROUP BY l.track_id
ORDER BY listen_count DESC
LIMIT $3 OFFSET $4
) x ) x
ORDER BY x.listen_count DESC, x.id JOIN tracks_with_title t ON x.track_id = t.id
LIMIT $3 OFFSET $4; JOIN releases r ON t.release_id = r.id
ORDER BY x.listen_count DESC, x.track_id;
-- name: GetTrackAllTimeRank :one -- name: GetTrackAllTimeRank :one
SELECT SELECT

View file

@ -353,13 +353,13 @@ func (q *Queries) GetReleasesWithoutImages(ctx context.Context, arg GetReleasesW
const getTopReleasesFromArtist = `-- name: GetTopReleasesFromArtist :many const getTopReleasesFromArtist = `-- name: GetTopReleasesFromArtist :many
SELECT SELECT
x.id, x.musicbrainz_id, x.image, x.various_artists, x.image_source, x.title, x.listen_count, x.artists, x.id, x.musicbrainz_id, x.image, x.various_artists, x.image_source, x.title, x.listen_count,
get_artists_for_release(x.id) AS artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM ( FROM (
SELECT SELECT
r.id, r.musicbrainz_id, r.image, r.various_artists, r.image_source, r.title, r.id, r.musicbrainz_id, r.image, r.various_artists, r.image_source, r.title,
COUNT(*) AS listen_count, COUNT(*) AS listen_count
get_artists_for_release(r.id) AS artists
FROM listens l FROM listens l
JOIN tracks t ON l.track_id = t.id JOIN tracks t ON l.track_id = t.id
JOIN releases_with_title r ON t.release_id = r.id JOIN releases_with_title r ON t.release_id = r.id
@ -430,13 +430,13 @@ func (q *Queries) GetTopReleasesFromArtist(ctx context.Context, arg GetTopReleas
const getTopReleasesPaginated = `-- name: GetTopReleasesPaginated :many const getTopReleasesPaginated = `-- name: GetTopReleasesPaginated :many
SELECT SELECT
x.id, x.musicbrainz_id, x.image, x.various_artists, x.image_source, x.title, x.listen_count, x.artists, x.id, x.musicbrainz_id, x.image, x.various_artists, x.image_source, x.title, x.listen_count,
get_artists_for_release(x.id) AS artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM ( FROM (
SELECT SELECT
r.id, r.musicbrainz_id, r.image, r.various_artists, r.image_source, r.title, r.id, r.musicbrainz_id, r.image, r.various_artists, r.image_source, r.title,
COUNT(*) AS listen_count, COUNT(*) AS listen_count
get_artists_for_release(r.id) AS artists
FROM listens l FROM listens l
JOIN tracks t ON l.track_id = t.id JOIN tracks t ON l.track_id = t.id
JOIN releases_with_title r ON t.release_id = r.id JOIN releases_with_title r ON t.release_id = r.id

View file

@ -155,33 +155,30 @@ func (q *Queries) GetAllTracksFromArtist(ctx context.Context, artistID int32) ([
const getTopTracksByArtistPaginated = `-- name: GetTopTracksByArtistPaginated :many const getTopTracksByArtistPaginated = `-- name: GetTopTracksByArtistPaginated :many
SELECT SELECT
x.id, x.track_id AS id,
x.title,
x.musicbrainz_id,
x.release_id,
x.image,
x.listen_count,
x.artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM (
SELECT
t.id,
t.title, t.title,
t.musicbrainz_id, t.musicbrainz_id,
t.release_id, t.release_id,
r.image, r.image,
x.listen_count,
get_artists_for_track(x.track_id) AS artists,
x.rank
FROM (
SELECT
l.track_id,
COUNT(*) AS listen_count, COUNT(*) AS listen_count,
get_artists_for_track(t.id) AS artists RANK() OVER (ORDER BY COUNT(*) DESC) as rank
FROM listens l FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id JOIN artist_tracks at ON l.track_id = at.track_id
JOIN releases r ON t.release_id = r.id
JOIN artist_tracks at ON at.track_id = t.id
WHERE l.listened_at BETWEEN $1 AND $2 WHERE l.listened_at BETWEEN $1 AND $2
AND at.artist_id = $5 AND at.artist_id = $5
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image GROUP BY l.track_id
) x ORDER BY listen_count DESC
ORDER BY x.listen_count DESC, x.id
LIMIT $3 OFFSET $4 LIMIT $3 OFFSET $4
) x
JOIN tracks_with_title t ON x.track_id = t.id
JOIN releases r ON t.release_id = r.id
ORDER BY x.listen_count DESC, x.track_id
` `
type GetTopTracksByArtistPaginatedParams struct { type GetTopTracksByArtistPaginatedParams struct {
@ -240,32 +237,30 @@ func (q *Queries) GetTopTracksByArtistPaginated(ctx context.Context, arg GetTopT
const getTopTracksInReleasePaginated = `-- name: GetTopTracksInReleasePaginated :many const getTopTracksInReleasePaginated = `-- name: GetTopTracksInReleasePaginated :many
SELECT SELECT
x.id, x.track_id AS id,
x.title,
x.musicbrainz_id,
x.release_id,
x.image,
x.listen_count,
x.artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM (
SELECT
t.id,
t.title, t.title,
t.musicbrainz_id, t.musicbrainz_id,
t.release_id, t.release_id,
r.image, r.image,
x.listen_count,
get_artists_for_track(x.track_id) AS artists,
x.rank
FROM (
SELECT
l.track_id,
COUNT(*) AS listen_count, COUNT(*) AS listen_count,
get_artists_for_track(t.id) AS artists RANK() OVER (ORDER BY COUNT(*) DESC) as rank
FROM listens l FROM listens l
JOIN tracks_with_title t ON l.track_id = t.id JOIN tracks t ON l.track_id = t.id
JOIN releases r ON t.release_id = r.id
WHERE l.listened_at BETWEEN $1 AND $2 WHERE l.listened_at BETWEEN $1 AND $2
AND t.release_id = $5 AND t.release_id = $5
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image GROUP BY l.track_id
) x ORDER BY listen_count DESC
ORDER BY x.listen_count DESC, x.id
LIMIT $3 OFFSET $4 LIMIT $3 OFFSET $4
) x
JOIN tracks_with_title t ON x.track_id = t.id
JOIN releases r ON t.release_id = r.id
ORDER BY x.listen_count DESC, x.track_id
` `
type GetTopTracksInReleasePaginatedParams struct { type GetTopTracksInReleasePaginatedParams struct {
@ -324,31 +319,28 @@ func (q *Queries) GetTopTracksInReleasePaginated(ctx context.Context, arg GetTop
const getTopTracksPaginated = `-- name: GetTopTracksPaginated :many const getTopTracksPaginated = `-- name: GetTopTracksPaginated :many
SELECT SELECT
x.id, x.track_id AS id,
x.title,
x.musicbrainz_id,
x.release_id,
x.image,
x.listen_count,
x.artists,
RANK() OVER (ORDER BY x.listen_count DESC) AS rank
FROM (
SELECT
t.id,
t.title, t.title,
t.musicbrainz_id, t.musicbrainz_id,
t.release_id, t.release_id,
r.image, r.image,
x.listen_count,
get_artists_for_track(x.track_id) AS artists,
x.rank
FROM (
SELECT
track_id,
COUNT(*) AS listen_count, COUNT(*) AS listen_count,
get_artists_for_track(t.id) AS artists RANK() OVER (ORDER BY COUNT(*) DESC) as rank
FROM listens l FROM listens
JOIN tracks_with_title t ON l.track_id = t.id WHERE listened_at BETWEEN $1 AND $2
JOIN releases r ON t.release_id = r.id GROUP BY track_id
WHERE l.listened_at BETWEEN $1 AND $2 ORDER BY listen_count DESC
GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image
) x
ORDER BY x.listen_count DESC, x.id
LIMIT $3 OFFSET $4 LIMIT $3 OFFSET $4
) x
JOIN tracks_with_title t ON x.track_id = t.id
JOIN releases r ON t.release_id = r.id
ORDER BY x.listen_count DESC, x.track_id
` `
type GetTopTracksPaginatedParams struct { type GetTopTracksPaginatedParams struct {