为什么我的查询成本如此之高?

时间:2015-03-30 10:48:13

标签: sql postgresql postgresql-9.3 optimization

当我对某些查询执行explain analyze时,我已经从一些低值到一些更高的值获得了正常的成本。但是当我试图通过将enable_seqscan切换为false来强制使用表上的索引时,查询成本会跳转到疯狂的值,如:

Merge Join  (cost=10064648609.460..10088218360.810 rows=564249 width=21) (actual time=341699.323..370702.969 rows=3875328 loops=1)
    Merge Cond: ((foxtrot.two = ((five_hotel.two)::numeric)) AND (foxtrot.alpha_two07 = ((five_hotel.alpha_two07)::numeric)))
  ->  Merge Append  (cost=10000000000.580..10023064799.260 rows=23522481 width=24) (actual time=0.049..19455.320 rows=23522755 loops=1)
          Sort Key: foxtrot.two, foxtrot.alpha_two07
        ->  Sort  (cost=10000000000.010..10000000000.010 rows=1 width=76) (actual time=0.005..0.005 rows=0 loops=1)
                Sort Key: foxtrot.two, foxtrot.alpha_two07
                Sort Method: quicksort  Memory: 25kB
              ->  Seq Scan on foxtrot  (cost=10000000000.000..10000000000.000 rows=1 width=76) (actual time=0.001..0.001 rows=0 loops=1)
                      Filter: (kilo_sierra_oscar = 'oscar'::date)
        ->  Index Scan using alpha_five on five_uniform  (cost=0.560..22770768.220 rows=23522480 width=24) (actual time=0.043..17454.619 rows=23522755 loops=1)
                Filter: (kilo_sierra_oscar = 'oscar'::date)

正如您所看到的,我正在尝试按索引检索值,因此一旦加载它们就不需要进行排序。

这是一个简单的查询:

select *
    from foxtrot a
      where foxtrot.kilo_sierra_oscar = date'2015-01-01'
      order by foxtrot.two, foxtrot.alpha_two07
  

索引扫描:“执行时间:19009.569 ms”

     

顺序扫描:“执行时间:127062.802 ms”

将enable_seqscan设置为false可以改善查询的执行时间,但我希望优化器能够计算出来。

修改

带缓冲区的Seq计划:

Sort  (cost=4607555.110..4666361.310 rows=23522481 width=24) (actual time=101094.754..120740.190 rows=23522756 loops=1)
    Sort Key: foxtrot.two, foxtrot.alpha07
    Sort Method: external merge  Disk: 805304kB
    Buffers: shared hit=468690, temp read=100684 written=100684
  ->  Append  (cost=0.000..762721.000 rows=23522481 width=24) (actual time=0.006..12018.725 rows=23522756 loops=1)
          Buffers: shared hit=468690
        ->  Seq Scan on foxtrot  (cost=0.000..0.000 rows=1 width=76) (actual time=0.001..0.001 rows=0 loops=1)
                Filter: (kilo = 'oscar'::date)
        ->  Seq Scan on foxtrot (cost=0.000..762721.000 rows=23522480 width=24) (actual time=0.005..9503.851 rows=23522756 loops=1)
                Filter: (kilo = 'oscar'::date)
                Buffers: shared hit=468690

带缓冲区的索引计划:

Merge Append  (cost=10000000000.580..10023064799.260 rows=23522481 width=24) (actual time=0.046..19302.855 rows=23522756 loops=1)
    Sort Key: foxtrot.two, foxtrot.alpha_two07
    Buffers: shared hit=17855133   ->  Sort  (cost=10000000000.010..10000000000.010 rows=1 width=76) (actual time=0.009..0.009 rows=0 loops=1)
          Sort Key: foxtrot.two, foxtrot.alpha_two07
          Sort Method: quicksort  Memory: 25kB
        ->  Seq Scan on foxtrot  (cost=10000000000.000..10000000000.000 rows=1 width=76) (actual time=0.000..0.000 rows=0 loops=1)
                Filter: (kilo = 'oscar'::date)
        ->  Index Scan using alpha_five on five  (cost=0.560..22770768.220 rows=23522480 width=24) (actual time=0.036..17035.903 rows=23522756 loops=1)
          Filter: (kilo = 'oscar'::date)
          Buffers: shared hit=17855133

为什么查询的成本会如此之高?我怎么能避免它?

1 个答案:

答案 0 :(得分:5)

高成本是set enable_seqscan=false的直接后果。

规划师实施了这个"提示"通过为顺序扫描技术设置任意超高成本(10 000 000 000)。然后,它计算不同的潜在执行策略及其相关成本。

如果最佳结果仍然具有超高成本,则意味着规划人员没有找到避免顺序扫描的策略,即使不惜一切代价 也是如此。

在"带缓冲区的索引计划"中的问题中显示的计划中这发生在 Seq Scan on foxtrot 节点上。