我正在通过外部数据包装器(postgres_fdw)运行带有 INNER JOIN 的查询,当我查看 EXPLAIN ANALYZE 时,它显示其中一个外部扫描子节点低估了它在实际扫描 7 时只会扫描 1 行导致查询花费比预期更长的时间,因为这会导致其他 Foreign Scan 子节点循环 7 次,这是查询的主要瓶颈。这是查询及其各自的解释分析:
SELECT ROUND(AVG(m.forecast - w.wind),6) from pjm.wind_forecast_recent w
INNER JOIN pjm.load_forecast_recent m ON w.pricedate = m.pricedate AND w.hour = m.hour
WHERE w.hour = 5 AND m.area = 'RTO_COMBINED' AND (w.pricedate BETWEEN (SELECT current_date-6) AND (SELECT current_date));
Aggregate (cost=842341.01..842341.02 rows=1 width=32) (actual time=77120.088..77120.089 rows=1 loops=1)
InitPlan 1 (returns $0)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.007..0.008 rows=1 loops=1)
InitPlan 2 (returns $1)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=1)
-> Nested Loop (cost=840333.25..842340.97 rows=1 width=18) (actual time=14719.661..77119.994 rows=7 loops=1)
-> Foreign Scan on wind_forecast_recent w (cost=242218.45..242218.49 rows=1 width=18) (actual time=3184.714..3184.720 rows=7 loops=1)
-> Foreign Scan on load_forecast_recent m (cost=598114.80..600122.47 rows=1 width=16) (actual time=10531.723..10531.724 rows=1 loops=7)
Planning Time: 744.979 ms
Execution Time: 77227.512 ms
在将 default_statistics_target 值提高到 1000 后,我尝试在两个表上运行 ANALYZE,但规划器没有改变。
我还应该注意,当我使用 BETWEEN 将查询的 WHERE 部分更改为一系列 OR 语句时,(w.priceate = (SELECT current_date-6) OR w.priceate = (SELECT current_date-5) OR...) ,查询不使用嵌套循环,运行速度是原来的 7 倍。我不太确定为什么使用 BETWEEN 或一系列 OR 语句会产生相同的结果,但我假设这与计划者低估了 Foreign Scan 中的行数有关。
我在 Ubuntu 18.04 服务器上运行 PostgreSQL 12.1。
如果您还有其他问题,请告诉我。谢谢!