Я выполняю запрос с INNER JOIN, в котором планировщик решает использовать вложенный L oop. Я выяснил, что это связано с условиями WHERE, так как я пытался написать запрос с различными условиями WHERE, поэтому он возвращает тот же результат, но не использует вложенный L oop.
Мой вопрос почему планировщик решил принимать разные решения, когда запросы кажутся идентичными, поскольку оба они возвращают один и тот же результат? Запрос выполняется за 77 секунд с Nested L oop и 13 se c без, а запрос, выполняемый за 13 se c, довольно уродлив и не элегантен, что заставляет меня думать, что есть лучший способ написать его.
Вот два запроса. Обратите внимание, что разница между ними заключается в том, как предложение WHERE фильтрует по дате, когда первый использует BETWEEN, а второй - серию операторов OR. Мне известно, что странно, что current_date обернут в их собственные подзапросы, но это потому, что эти запросы используют сторонние обертки данных. Это позволяет передавать current_date как неизменяемый объект, что значительно ускоряет производительность.
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));
-----------
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 = (SELECT current_date-6) OR
w.pricedate = (SELECT current_date-5) OR
w.pricedate = (SELECT current_date-4) OR
w.pricedate = (SELECT current_date-3) OR
w.pricedate = (SELECT current_date-2) OR
w.pricedate = (SELECT current_date-1) OR
w.pricedate = (SELECT current_date))
А вот соответствующий EXPLAIN ANALYZE:
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
Aggregate (cost=841657.94..841657.95 rows=1 width=32) (actual time=13683.022..13683.023 rows=1 loops=1)
InitPlan 1 (returns $0)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.006..0.006 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)
InitPlan 3 (returns $2)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=1)
InitPlan 4 (returns $3)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=1)
InitPlan 5 (returns $4)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=1)
InitPlan 6 (returns $5)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=1)
InitPlan 7 (returns $6)
-> Result (cost=0.00..0.01 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=1)
-> Foreign Scan (cost=833725.15..841657.83 rows=1 width=18) (actual time=13682.974..13682.977 rows=7 loops=1)
Relations: (pjm.wind_forecast_recent w) INNER JOIN (pjm.load_forecast_recent m)
Planning Time: 332.870 ms
JIT:
Functions: 16
Options: Inlining true, Optimization true, Expressions true, Deforming true
Timing: Generation 4.163 ms, Inlining 15.088 ms, Optimization 44.489 ms, Emission 28.064 ms, Total 91.804 ms
Execution Time: 13724.094 ms
Я работаю PostgreSQL 12.1 на сервере Ubuntu 18.04.
Дайте мне знать, если у вас есть дополнительные вопросы. Спасибо!