有可能加快此查询的速度吗?

时间:2019-01-01 00:11:21

标签: sql postgresql

我有以下查询,该查询执行时间过长。我已经为查询发布了EXPLAIN ANALYZE。我能做些什么来提高速度?

EXPLAIN analyze SELECT c.*, match.user_json FROM match INNER JOIN conversation c 
ON match.match_id = c.match_id WHERE c.from_id <> 142822281 AND c.to_id = 
142822281 AND c.unix_timestamp = (SELECT max( unix_timestamp ) FROM conversation 
WHERE match_id = c.match_id GROUP BY match_id) 

EXPLAIN ANALYZE结果

Nested Loop  (cost=0.00..16183710.79 rows=2 width=805) (actual time=2455.133..2502.781 rows=34 loops=1)
  Join Filter: (match.match_id = c.match_id)
  Rows Removed by Join Filter: 71502
  ->  Seq Scan on match  (cost=0.00..268.51 rows=2151 width=723) (actual time=0.006..4.973 rows=2104 loops=1)
  ->  Materialize  (cost=0.00..16183377.75 rows=2 width=90) (actual time=0.034..1.168 rows=34 loops=2104)
        ->  Seq Scan on conversation c  (cost=0.00..16183377.74 rows=2 width=90) (actual time=70.972..2421.949 rows=34 loops=1)
              Filter: ((from_id <> 142822281) AND (to_id = 142822281) AND (unix_timestamp = (SubPlan 1)))
              Rows Removed by Filter: 22010
              SubPlan 1
                ->  GroupAggregate  (cost=0.00..739.64 rows=10 width=16) (actual time=5.358..5.358 rows=1 loops=450)
                      Group Key: conversation.match_id
                      ->  Seq Scan on conversation  (cost=0.00..739.49 rows=10 width=16) (actual time=3.355..5.320 rows=17 loops=450)
                            Filter: (match_id = c.match_id)
                            Rows Removed by Filter: 22027
Planning Time: 1.132 ms
Execution Time: 2502.926 ms

1 个答案:

答案 0 :(得分:2)

这是您的查询:

SELECT c.*, m.user_json
FROM match m INNER JOIN
     conversation c 
     ON m.match_id = c.match_id
WHERE c.from_id <> 142822281 AND 
      c.to_id = 142822281 AND
      c.unix_timestamp = (SELECT max( c2.unix_timestamp )
                          FROM conversation c2
                          WHERE c2.match_id = c.match_id
                          GROUP BY c2.match_id
                         );

我建议将其写为:

SELECT DISTINCT ON (c.match_id) c.*, m.user_json
FROM match m INNER JOIN
     conversation c 
     ON m.match_id = c.match_id
WHERE c.from_id <> 142822281 AND 
      c.to_id = 142822281 AND
ORDER BY c.match_id, c.unix_timestamp DESC;

然后尝试在conversation(to_id, from_id, match_id)上建立索引。我假设您在match(match_id)上有一个索引。