Postgresql 采用嵌套循环而不是哈希联接的查询

Postgresql 采用嵌套循环而不是哈希联接的查询,postgresql,Postgresql,下面的查询是嵌套循环,运行21分钟,禁用嵌套循环后,它将在

下面的查询是嵌套循环,运行21分钟,禁用嵌套循环后,它将在<1分钟内工作。表的统计信息是最新的,并且在表上运行vacuum,这可以解释为什么postgres采用嵌套循环而不是高效的哈希连接

另外,要禁用嵌套循环,最好将enable_nestloop设置为off还是增加随机页面成本?我认为将nestloop设置为off会阻止计划使用nestloop,如果它在某些地方是有效的。有什么更好的选择,请告知

SELECT DISTINCT ON (three.quebec_delta)
    last_value(three.reviewed_by_nm) OVER wnd AS reviewed_by_nm,
    last_value(three.reviewer_specialty_nm) OVER wnd AS reviewer_specialty_nm,
    last_value(three.kilo) OVER wnd AS kilo,
    last_value(three.review_reason_dscr) OVER wnd AS review_reason_dscr,
    last_value(three.review_notes) OVER wnd AS review_notes,
    last_value(three.seven_uniform_charlie) OVER wnd AS seven_uniform_charlie,
    last_value(three.di_audit_source_system_cd) OVER wnd AS di_audit_source_system_cd,
    last_value(three.di_audit_update_dtm) OVER wnd AS di_audit_update_dtm,
    three.quebec_delta
FROM
    ods_authorization.quebec_foxtrot seven_uniform_foxtrot
    JOIN ods_authorization.golf echo ON seven_uniform_foxtrot.four = echo.oscar
    JOIN ods_authorization.papa three ON echo.five = three.quebec_delta
        AND three.xray = '0'::bpchar
WHERE
    seven_uniform_foxtrot.two_india >= (zulu () - '2 years'::interval)
    AND lima (three.kilo, 'ADVISOR'::character varying)::text = 'ADVISOR'::text
WINDOW wnd AS (PARTITION BY three.quebec_delta ORDER BY three.seven_uniform_charlie DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
计划运行21米并采取嵌套循环

Unique  (cost=550047.63..550257.15 rows=5238 width=281) (actual time=1295000.966..1296128.356 rows=319863 loops=1)
  ->  WindowAgg  (cost=550047.63..550244.06 rows=5238 width=281) (actual time=1295000.964..1296013.046 rows=461635 loops=1)
        ->  Sort  (cost=550047.63..550060.73 rows=5238 width=326) (actual time=1295000.929..1295089.796 rows=461635 loops=1)
                Sort Key: three.quebec_delta, three.seven_uniform_charlie DESC
                Sort Method: quicksort  Memory: 197021kB
              ->  Nested Loop  (cost=1001.12..549724.06 rows=5238 width=326) (actual time=8.274..1292470.826 rows=461635 loops=1)
                    ->  Gather  (cost=1000.56..527782.84 rows=24896 width=391) (actual time=4.287..12701.687 rows=3484699 loops=1)
                            Workers Planned: 2
                            Workers Launched: 2
                          ->  Nested Loop  (cost=0.56..524293.24 rows=10373 width=391) (actual time=3.492..400998.923 rows=1161566 loops=3)
                                ->  Parallel Seq Scan on papa three  (cost=0.00..436912.84 rows=10373 width=326) (actual time=1.554..2455.626 rows=1161566 loops=3)
                                        Filter: ((xray = 'november'::bpchar) AND ((lima_sierra(kilo, 'two_zulu'::character varying))::text = 'two_zulu'::text))
                                        Rows Removed by Filter: 501723
                                ->  Index Scan using five_tango on golf echo  (cost=0.56..8.42 rows=1 width=130) (actual time=0.342..0.342 rows=1 loops=3484699)
                                        Index Cond: (five_hotel = three.quebec_delta)
                    ->  Index Scan using lima_alpha on quebec_foxtrot seven_uniform_foxtrot  (cost=0.56..0.88 rows=1 width=65) (actual time=0.366..0.366 rows=0 loops=3484699)
                            Index Cond: (four = echo.oscar)
                            Filter: (two_india >= (zulu() - 'two_two'::interval))
                            Rows Removed by Filter: 1
Planning time: 0.777 ms
Execution time: 1296183.259 ms
将enable_nestloop设置为off并将work_mem设置为8GB后进行计划。当随机页面成本增加到1000时,我得到了相同的计划

Unique  (cost=5933437.24..5933646.68 rows=5236 width=281) (actual time=19898.050..20993.124 rows=319980 loops=1)
  ->  WindowAgg  (cost=5933437.24..5933633.59 rows=5236 width=281) (actual time=19898.049..20879.655 rows=461769 loops=1)
        ->  Sort  (cost=5933437.24..5933450.33 rows=5236 width=326) (actual time=19898.022..19978.839 rows=461769 loops=1)
                Sort Key: three.quebec_delta, three.seven_uniform_charlie DESC
                Sort Method: quicksort  Memory: 197056kB
              ->  Hash Join  (cost=1947451.87..5933113.80 rows=5236 width=326) (actual time=11616.323..17931.146 rows=461769 loops=1)
                      Hash Cond: (echo.oscar = seven_uniform_foxtrot.four)
                    ->  Gather  (cost=438059.74..4423656.32 rows=24897 width=391) (actual time=1909.685..7291.289 rows=3484833 loops=1)
                            Workers Planned: 2
                            Workers Launched: 2
                          ->  Parallel Hash Join  (cost=437059.74..4420166.62 rows=10374 width=391) (actual time=1904.546..7385.948 rows=1161611 loops=3)
                                  Hash Cond: (echo.five = three.quebec_delta)
                                ->  Parallel Seq Scan on golf echo  (cost=0.00..3921922.09 rows=8152209 width=130) (actual time=0.003..1756.576 rows=6531668 loops=3)
                                ->  Parallel Hash  (cost=436930.07..436930.07 rows=10374 width=326) (actual time=1904.354..1904.354 rows=1161611 loops=3)
                                        Buckets: 4194304 (originally 32768)  Batches: 1 (originally 1)  Memory Usage: 1135200kB
                                      ->  Parallel Seq Scan on papa three  (cost=0.00..436930.07 rows=10374 width=326) (actual time=0.009..963.728 rows=1161611 loops=3)
                                              Filter: ((xray = 'november'::bpchar) AND ((lima(kilo, 'two_zulu'::character varying))::text = 'two_zulu'::text))
                                              Rows Removed by Filter: 502246
                    ->  Hash  (cost=1476106.74..1476106.74 rows=2662831 width=65) (actual time=9692.517..9692.517 rows=2685656 loops=1)
                            Buckets: 4194304  Batches: 1  Memory Usage: 287171kB
                          ->  Seq Scan on quebec_foxtrot seven_uniform_foxtrot  (cost=0.00..1476106.74 rows=2662831 width=65) (actual time=0.026..8791.556 rows=2685656 loops=1)
                                  Filter: (two_india >= (zulu() - 'two_two'::interval))
                                  Rows Removed by Filter: 9984069
Planning time: 0.742 ms
Execution time: 21218.770 ms

papa上尝试索引(lima_sierra(kilo,'two_zulu':字符变化))
分析表。有了该索引,PostgreSQL将收集表达式的统计信息,这将改进估计,从而不会得到嵌套的循环联接。

尝试在
papa(lima_sierra(kilo,'two_zulu'::character variable))上建立索引。
分析表。有了该索引,PostgreSQL将收集表达式的统计信息,这将改进估计值,这样就不会得到嵌套的循环联接。

如果您只是将COALESCE(r\u cd,'ADVISOR')='ADVISOR'
替换为

(r_cd = 'ADVISOR' or r_cd IS NULL)

这可能会使用当前的表统计信息来改进估计值,使之足以更改计划。

如果您只是将
COALESCE(r\u cd,'ADVISOR')='ADVISOR'
替换为

(r_cd = 'ADVISOR' or r_cd IS NULL)

这可能会使用当前的表统计信息来改进估计值,从而足以更改计划。

您能告诉我们lima_sierra函数的实际内容吗?它的-Filter:((d_flg='0'::bpchar)和((COALESCE(r_cd,'ADVISOR'::character variable))::text='ADVISOR'::text))。用于屏蔽原始查询的标识。您能告诉我们函数lima_sierra实际上是什么吗?它的-Filter:((d_flg='0'::bpchar)和((COALESCE(r_cd,'ADVISOR'::character variabling))::text='ADVISOR'::text))。用于掩盖原始查询的身份。谢谢,这也起作用。谢谢,这也起作用。谢谢,这起作用了。谢谢,这起作用了。谢谢,这起作用了。