代码之家  ›  专栏  ›  技术社区  ›  Arya

是否可以加速此查询?

  •  0
  • Arya  · 技术社区  · 6 年前

    我有以下查询,执行起来有点太长。我已经发布了 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) 
    

    解释分析结果

    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 回复  |  直到 6 年前
        1
  •  2
  •   Gordon Linoff    6 年前

    这是您的查询:

    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) .