为什么我的查询成本这么高?

Why my query cost is so high?

当我对某些查询执行解释分析时,我得到了从低值到高值的正常成本。但是当我试图通过将 enable_seqscan 切换为 false 来强制使用 table 上的索引时,查询成本会跳到疯狂的值,例如:

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

Index scan: "Execution time: 19009.569 ms"

Sequential scan: "Execution time: 127062.802 ms"

将 enable_seqscan 设置为 false 可以缩短查询的执行时间,但我希望优化器能够对其进行计算。

编辑:

带缓冲区的序列计划:

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

为什么查询的成本跳这么高?我怎样才能避免它?

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

规划器通过为顺序扫描技术设置任意超高成本(10 000 000 000)来实现此"hint"。然后它计算不同的潜在执行策略及其相关成本。

如果最好的结果仍然有超高的成本,这意味着规划者没有找到避免顺序扫描的策略,即使在不惜一切代价尝试时

在 "Index plan with buffers" 下问题中显示的计划中,这发生在 foxtrot 节点上的序列扫描。