我需要索引吗?

时间:2018-04-27 15:21:48

标签: sql postgresql query-optimization

我有以下相当复杂的SQL查询

explain 
select m.* 
from conversation m 
where m.from_tel <>'12030000000' 
  and m.to_tel = '12030000000' 
  AND m.insert_time > NOW() - INTERVAL '2 days' 
  AND m.insert_time = (select max(insert_time) 
                       from conversation 
                       where match_id = m.match_id 
                       group by match_id)  
  AND insert_time < NOW() - INTERVAL '70 seconds' 
  AND ((select count(*) 
        from conversation as sl 
        where sl.match_id = m.match_id 
          and sl.reply_batch = true) < 8)

我认为它会大幅增加服务器负载,下面是我的explain结果

Seq Scan on conversation m  (cost=0.00..27219931.46 rows=3 width=110)
  Filter: ((from_tel <> '12030000000'::text) AND (to_tel = '12030000000'::text) AND (insert_time > (now() - '2 days'::interval)) AND (insert_time < (now() - '00:01:10'::interval)) AND ((SubPlan 2) < 8) AND (insert_time = (SubPlan 1)))
  SubPlan 2
    ->  Aggregate  (cost=651.92..651.93 rows=1 width=8)
          ->  Seq Scan on conversation sl  (cost=0.00..651.90 rows=7 width=0)
                Filter: (reply_batch AND (match_id = m.match_id))
  SubPlan 1
    ->  GroupAggregate  (cost=0.00..652.16 rows=17 width=30)
          Group Key: conversation.match_id
          ->  Seq Scan on conversation  (cost=0.00..651.90 rows=17 width=30)
                Filter: (match_id = m.match_id)

以下是我的分析缓冲区

Seq Scan on conversation m  (cost=0.00..27219931.46 rows=3 width=110) (actual time=12049.732..12049.732 rows=0 loops=1)
  Filter: ((from_tel <> '12030000000'::text) AND (to_tel = '12030000000'::text) AND (insert_time > (now() - '2 days'::interval)) AND (insert_time < (now() - '00:01:10'::interval)) AND ((SubPlan 2) < 8) AND (insert_time = (SubPlan 1)))
  Rows Removed by Filter: 20880
  Buffers: shared hit=1115914
  SubPlan 2
    ->  Aggregate  (cost=651.92..651.93 rows=1 width=8) (actual time=4.114..4.114 rows=1 loops=2429)
          Buffers: shared hit=949739
          ->  Seq Scan on conversation sl  (cost=0.00..651.90 rows=7 width=0) (actual time=2.673..4.105 rows=8 loops=2429)
                Filter: (reply_batch AND (match_id = m.match_id))
                Rows Removed by Filter: 20872
                Buffers: shared hit=949739
  SubPlan 1
    ->  GroupAggregate  (cost=0.00..652.16 rows=17 width=30) (actual time=4.785..4.785 rows=1 loops=424)
          Group Key: conversation.match_id
          Buffers: shared hit=165784
          ->  Seq Scan on conversation  (cost=0.00..651.90 rows=17 width=30) (actual time=3.030..4.773 rows=15 loops=424)
                Filter: (match_id = m.match_id)
                Rows Removed by Filter: 20865
                Buffers: shared hit=165784
Planning time: 0.698 ms
Execution time: 12049.855 ms

看起来SubPlan 2花了很多时间。是什么造成的?我需要索引吗?如果是这样哪些列?

1 个答案:

答案 0 :(得分:0)

我添加了两个索引,一个在reply_batchmatch_id

执行时间:71.812 ms