Reputation: 1051
I am having a problem with this query running on a table with 550k rows
SELECT "items".* FROM "items"
WHERE (items.player_id = '1')
GROUP BY items.id
ORDER BY items.created_at DESC
LIMIT 50 OFFSET 0
The explain analyse indicates a serious problem with the ORDER BY part, which is taking 5.7 secs.
"Limit (cost=64509.79..64509.91 rows=50 width=550) (actual time=5767.488..5767.499 rows=50 loops=1)"
" -> Sort (cost=64509.79..65867.39 rows=543041 width=550) (actual time=5767.486..5767.492 rows=50 loops=1)"
" Sort Key: created_at"
" Sort Method: top-N heapsort Memory: 50kB"
" -> Group (cost=0.42..46470.36 rows=543041 width=550) (actual time=0.105..2668.933 rows=543024 loops=1)"
" -> Index Scan using items_pkey on items (cost=0.42..45112.76 rows=543041 width=550) (actual time=0.099..989.441 rows=543024 loops=1)"
" Filter: (player_id = 1)"
" Rows Removed by Filter: 252"
"Total runtime: 5767.814 ms"
I have indexes on items.id, items.created_at, items.player_id, (items.id, items.created_at), (items.player_id, items.created_at), (items.id, items.player_id, items.created_at)
Upvotes: 0
Views: 1318
Reputation: 214
Basically you don't need to the GROUP BY clause, as this works only with aggregate functions, so remove that GROUP BY and the query performance will definitely get better.
Upvotes: 1
Reputation: 1271003
Why do you need the group by
? The aggregation only works when items.id
is unique -- which in turn means that the aggregation is not needed.
SELECT i.*
FROM items i
WHERE (i.player_id = '1')
ORDER BY items.created_at DESC
LIMIT 50 OFFSET 0;
You can then improve this query by adding an index on items(player_id, created_at)
.
Upvotes: 2