From 16cee8cfcababb84e93ba4793fb57e53993a942b Mon Sep 17 00:00:00 2001 From: Gabe Farrell <90876006+gabehf@users.noreply.github.com> Date: Wed, 21 Jan 2026 17:30:59 -0500 Subject: [PATCH] fix: speedup top-artists and top-albums queries (#167) --- db/queries/release.sql | 8 +-- db/queries/track.sql | 110 +++++++++++++---------------- internal/repository/release.sql.go | 12 ++-- internal/repository/track.sql.go | 110 +++++++++++++---------------- 4 files changed, 112 insertions(+), 128 deletions(-) diff --git a/db/queries/release.sql b/db/queries/release.sql index 47aac86..23bd2f2 100644 --- a/db/queries/release.sql +++ b/db/queries/release.sql @@ -48,12 +48,12 @@ WHERE r.title = ANY ($1::TEXT[]) -- name: GetTopReleasesFromArtist :many SELECT x.*, + get_artists_for_release(x.id) AS artists, RANK() OVER (ORDER BY x.listen_count DESC) AS rank FROM ( SELECT r.*, - COUNT(*) AS listen_count, - get_artists_for_release(r.id) AS artists + COUNT(*) AS listen_count FROM listens l JOIN tracks t ON l.track_id = t.id JOIN releases_with_title r ON t.release_id = r.id @@ -68,12 +68,12 @@ LIMIT $3 OFFSET $4; -- name: GetTopReleasesPaginated :many SELECT x.*, + get_artists_for_release(x.id) AS artists, RANK() OVER (ORDER BY x.listen_count DESC) AS rank FROM ( SELECT r.*, - COUNT(*) AS listen_count, - get_artists_for_release(r.id) AS artists + COUNT(*) AS listen_count FROM listens l JOIN tracks t ON l.track_id = t.id JOIN releases_with_title r ON t.release_id = r.id diff --git a/db/queries/track.sql b/db/queries/track.sql index c69bed5..3be4d7e 100644 --- a/db/queries/track.sql +++ b/db/queries/track.sql @@ -39,90 +39,82 @@ HAVING COUNT(DISTINCT at.artist_id) = cardinality($3::int[]); -- name: GetTopTracksPaginated :many SELECT - x.id, - x.title, - x.musicbrainz_id, - x.release_id, - x.image, + x.track_id AS id, + t.title, + t.musicbrainz_id, + t.release_id, + r.image, x.listen_count, - x.artists, - RANK() OVER (ORDER BY x.listen_count DESC) AS rank + get_artists_for_track(x.track_id) AS artists, + x.rank FROM ( SELECT - t.id, - t.title, - t.musicbrainz_id, - t.release_id, - r.image, + track_id, COUNT(*) AS listen_count, - get_artists_for_track(t.id) AS artists - FROM listens l - JOIN tracks_with_title t ON l.track_id = t.id - JOIN releases r ON t.release_id = r.id - WHERE l.listened_at BETWEEN $1 AND $2 - GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image + RANK() OVER (ORDER BY COUNT(*) DESC) as rank + FROM listens + WHERE listened_at BETWEEN $1 AND $2 + GROUP BY track_id + ORDER BY listen_count DESC + LIMIT $3 OFFSET $4 ) x -ORDER BY x.listen_count DESC, x.id -LIMIT $3 OFFSET $4; +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; -- name: GetTopTracksByArtistPaginated :many SELECT - x.id, - x.title, - x.musicbrainz_id, - x.release_id, - x.image, + x.track_id AS id, + t.title, + t.musicbrainz_id, + t.release_id, + r.image, x.listen_count, - x.artists, - RANK() OVER (ORDER BY x.listen_count DESC) AS rank + get_artists_for_track(x.track_id) AS artists, + x.rank FROM ( SELECT - t.id, - t.title, - t.musicbrainz_id, - t.release_id, - r.image, + l.track_id, COUNT(*) AS listen_count, - get_artists_for_track(t.id) AS artists + RANK() OVER (ORDER BY COUNT(*) DESC) as rank FROM listens l - JOIN tracks_with_title t ON l.track_id = t.id - JOIN releases r ON t.release_id = r.id - JOIN artist_tracks at ON at.track_id = t.id + JOIN artist_tracks at ON l.track_id = at.track_id WHERE l.listened_at BETWEEN $1 AND $2 - AND at.artist_id = $5 - GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image + AND at.artist_id = $5 + GROUP BY l.track_id + ORDER BY listen_count DESC + LIMIT $3 OFFSET $4 ) x -ORDER BY x.listen_count DESC, x.id -LIMIT $3 OFFSET $4; +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; -- name: GetTopTracksInReleasePaginated :many SELECT - x.id, - x.title, - x.musicbrainz_id, - x.release_id, - x.image, + x.track_id AS id, + t.title, + t.musicbrainz_id, + t.release_id, + r.image, x.listen_count, - x.artists, - RANK() OVER (ORDER BY x.listen_count DESC) AS rank + get_artists_for_track(x.track_id) AS artists, + x.rank FROM ( SELECT - t.id, - t.title, - t.musicbrainz_id, - t.release_id, - r.image, + l.track_id, COUNT(*) AS listen_count, - get_artists_for_track(t.id) AS artists + RANK() OVER (ORDER BY COUNT(*) DESC) as rank FROM listens l - JOIN tracks_with_title t ON l.track_id = t.id - JOIN releases r ON t.release_id = r.id + JOIN tracks t ON l.track_id = t.id WHERE l.listened_at BETWEEN $1 AND $2 - AND t.release_id = $5 - GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image + AND t.release_id = $5 + GROUP BY l.track_id + ORDER BY listen_count DESC + LIMIT $3 OFFSET $4 ) x -ORDER BY x.listen_count DESC, x.id -LIMIT $3 OFFSET $4; +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; -- name: GetTrackAllTimeRank :one SELECT diff --git a/internal/repository/release.sql.go b/internal/repository/release.sql.go index 6d12da4..f62e086 100644 --- a/internal/repository/release.sql.go +++ b/internal/repository/release.sql.go @@ -353,13 +353,13 @@ func (q *Queries) GetReleasesWithoutImages(ctx context.Context, arg GetReleasesW const getTopReleasesFromArtist = `-- name: GetTopReleasesFromArtist :many 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 FROM ( SELECT r.id, r.musicbrainz_id, r.image, r.various_artists, r.image_source, r.title, - COUNT(*) AS listen_count, - get_artists_for_release(r.id) AS artists + COUNT(*) AS listen_count FROM listens l JOIN tracks t ON l.track_id = t.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 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 FROM ( SELECT r.id, r.musicbrainz_id, r.image, r.various_artists, r.image_source, r.title, - COUNT(*) AS listen_count, - get_artists_for_release(r.id) AS artists + COUNT(*) AS listen_count FROM listens l JOIN tracks t ON l.track_id = t.id JOIN releases_with_title r ON t.release_id = r.id diff --git a/internal/repository/track.sql.go b/internal/repository/track.sql.go index e2aa084..b376198 100644 --- a/internal/repository/track.sql.go +++ b/internal/repository/track.sql.go @@ -155,33 +155,30 @@ func (q *Queries) GetAllTracksFromArtist(ctx context.Context, artistID int32) ([ const getTopTracksByArtistPaginated = `-- name: GetTopTracksByArtistPaginated :many SELECT - x.id, - x.title, - x.musicbrainz_id, - x.release_id, - x.image, + x.track_id AS id, + t.title, + t.musicbrainz_id, + t.release_id, + r.image, x.listen_count, - x.artists, - RANK() OVER (ORDER BY x.listen_count DESC) AS rank + get_artists_for_track(x.track_id) AS artists, + x.rank FROM ( SELECT - t.id, - t.title, - t.musicbrainz_id, - t.release_id, - r.image, + l.track_id, COUNT(*) AS listen_count, - get_artists_for_track(t.id) AS artists + RANK() OVER (ORDER BY COUNT(*) DESC) as rank FROM listens l - JOIN tracks_with_title t ON l.track_id = t.id - JOIN releases r ON t.release_id = r.id - JOIN artist_tracks at ON at.track_id = t.id + JOIN artist_tracks at ON l.track_id = at.track_id WHERE l.listened_at BETWEEN $1 AND $2 - AND at.artist_id = $5 - GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image + AND at.artist_id = $5 + GROUP BY l.track_id + ORDER BY listen_count DESC + LIMIT $3 OFFSET $4 ) x -ORDER BY x.listen_count DESC, x.id -LIMIT $3 OFFSET $4 +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 { @@ -240,32 +237,30 @@ func (q *Queries) GetTopTracksByArtistPaginated(ctx context.Context, arg GetTopT const getTopTracksInReleasePaginated = `-- name: GetTopTracksInReleasePaginated :many SELECT - x.id, - x.title, - x.musicbrainz_id, - x.release_id, - x.image, + x.track_id AS id, + t.title, + t.musicbrainz_id, + t.release_id, + r.image, x.listen_count, - x.artists, - RANK() OVER (ORDER BY x.listen_count DESC) AS rank + get_artists_for_track(x.track_id) AS artists, + x.rank FROM ( SELECT - t.id, - t.title, - t.musicbrainz_id, - t.release_id, - r.image, + l.track_id, COUNT(*) AS listen_count, - get_artists_for_track(t.id) AS artists + RANK() OVER (ORDER BY COUNT(*) DESC) as rank FROM listens l - JOIN tracks_with_title t ON l.track_id = t.id - JOIN releases r ON t.release_id = r.id + JOIN tracks t ON l.track_id = t.id WHERE l.listened_at BETWEEN $1 AND $2 - AND t.release_id = $5 - GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image + AND t.release_id = $5 + GROUP BY l.track_id + ORDER BY listen_count DESC + LIMIT $3 OFFSET $4 ) x -ORDER BY x.listen_count DESC, x.id -LIMIT $3 OFFSET $4 +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 { @@ -324,31 +319,28 @@ func (q *Queries) GetTopTracksInReleasePaginated(ctx context.Context, arg GetTop const getTopTracksPaginated = `-- name: GetTopTracksPaginated :many SELECT - x.id, - x.title, - x.musicbrainz_id, - x.release_id, - x.image, + x.track_id AS id, + t.title, + t.musicbrainz_id, + t.release_id, + r.image, x.listen_count, - x.artists, - RANK() OVER (ORDER BY x.listen_count DESC) AS rank + get_artists_for_track(x.track_id) AS artists, + x.rank FROM ( SELECT - t.id, - t.title, - t.musicbrainz_id, - t.release_id, - r.image, + track_id, COUNT(*) AS listen_count, - get_artists_for_track(t.id) AS artists - FROM listens l - JOIN tracks_with_title t ON l.track_id = t.id - JOIN releases r ON t.release_id = r.id - WHERE l.listened_at BETWEEN $1 AND $2 - GROUP BY t.id, t.title, t.musicbrainz_id, t.release_id, r.image + RANK() OVER (ORDER BY COUNT(*) DESC) as rank + FROM listens + WHERE listened_at BETWEEN $1 AND $2 + GROUP BY track_id + ORDER BY listen_count DESC + LIMIT $3 OFFSET $4 ) x -ORDER BY x.listen_count DESC, x.id -LIMIT $3 OFFSET $4 +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 {