使用GROUP BY,ORDER BY和LIMIT缓慢查询性能

时间:2014-02-26 12:15:15

标签: sql postgresql

我在使用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)

2 个答案:

答案 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,查询性能一定会好转。