我在使用550k行
的表上运行此查询时遇到问题SELECT "items".* FROM "items"
WHERE (items.player_id = '1')
GROUP BY items.id
ORDER BY items.created_at DESC
LIMIT 50 OFFSET 0
解释分析表明ORDER BY部分存在严重问题,需要5.7秒。
"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"
我在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)
答案 0 :(得分:2)
为什么需要group by
?聚合仅在items.id
唯一时才有效 - 这反过来意味着不需要聚合。
SELECT i.*
FROM items i
WHERE (i.player_id = '1')
ORDER BY items.created_at DESC
LIMIT 50 OFFSET 0;
然后,您可以通过在items(player_id, created_at)
上添加索引来改进此查询。
答案 1 :(得分:1)
基本上你不需要GROUP BY子句,因为这只适用于聚合函数,所以删除GROUP BY,查询性能一定会好转。