Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions api/v1_track_top_listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,17 @@ func (app *ApiServer) v1TrackTopListeners(c *fiber.Ctx) error {
}

sql := `
WITH deduped AS (
SELECT DISTINCT play_item_id, user_id, date_trunc('hour', created_at) as created_at
SELECT c.user_id, c.play_count
FROM (
SELECT user_id,
count(DISTINCT date_trunc('hour', created_at)) AS play_count
FROM plays
WHERE user_id IS NOT NULL
AND play_item_id = @trackId
),
counted as (
SELECT user_id, count(*) as play_count
FROM deduped
GROUP BY 1
)
SELECT counted.user_id, counted.play_count
FROM counted
LEFT JOIN aggregate_user USING (user_id)
ORDER BY play_count DESC, follower_count DESC, counted.user_id ASC
GROUP BY user_id
) c
LEFT JOIN aggregate_user au USING (user_id)
ORDER BY c.play_count DESC, au.follower_count DESC NULLS LAST, c.user_id ASC
LIMIT @limit
OFFSET @offset
`
Expand Down
10 changes: 10 additions & 0 deletions ddl/migrations/0190_add_plays_top_listeners_index.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
BEGIN;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you do some analysis on this index - it's going to be HUGE. it's probably fine, but the plays table is massive. basically run it against prod, and then figure out the size of the index


-- Add index optimized for top_listeners query
-- This index allows efficient filtering by play_item_id and supports
-- the count(distinct date_trunc('hour', created_at)) operation
CREATE INDEX IF NOT EXISTS ix_plays_play_item_user_date
ON plays(play_item_id, user_id, created_at)
WHERE user_id IS NOT NULL;

COMMIT;