Perf ROOT CAUSE: rolling faktor se počítal per řádek — hoist do proměnné (canonical PV fn 4.5s→~0.45s)
Skutečná příčina 600k buffers: CTE factor/factor_raw (single-ref) PG inlinuje do projekce with_factor → fn_pv_forecast_correction_factor (48 ms / 1.9k buffers) se vyhodnocovala ~300× per výstupní slot. Plan cache s tím neměl nic společného (dřívější count(*) měření projekci zahodilo, proto vycházelo 0.42 s). Faktor se teď počítá jednou do v_rolling_factor a vkládá jako literál (13. argument format). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,21 @@ set work_mem = '64MB'
|
|||||||
as $fn$
|
as $fn$
|
||||||
declare
|
declare
|
||||||
v_result jsonb;
|
v_result jsonb;
|
||||||
|
v_rolling_factor numeric;
|
||||||
begin
|
begin
|
||||||
|
-- Rolling faktor JEDNOU do proměnné: jako inlinovaná CTE (single-ref) se
|
||||||
|
-- fn_pv_forecast_correction_factor vyhodnocovala per výstupní řádek
|
||||||
|
-- (~300× ≈ 570k buffers / ~4 s — skutečná příčina pomalosti, ne plan cache).
|
||||||
|
v_rolling_factor := coalesce(
|
||||||
|
(ems.fn_pv_forecast_correction_factor(
|
||||||
|
p_site_id,
|
||||||
|
(p_now - (p_factor_window_h::text || ' hours')::interval)::timestamptz,
|
||||||
|
p_now,
|
||||||
|
p_factor_min_clamp,
|
||||||
|
p_factor_max_clamp
|
||||||
|
)->>'correction_factor')::numeric,
|
||||||
|
1.0
|
||||||
|
);
|
||||||
-- PG 18 cachuje plán SQL/plpgsql statementů s parametry → generický plán
|
-- PG 18 cachuje plán SQL/plpgsql statementů s parametry → generický plán
|
||||||
-- (4.5–9 s / 600k buffers); force_custom_plan na funkci nepomohl. Execute
|
-- (4.5–9 s / 600k buffers); force_custom_plan na funkci nepomohl. Execute
|
||||||
-- s literály vynutí čerstvý plán dle skutečných hodnot: 0.4 s / 34k buffers.
|
-- s literály vynutí čerstvý plán dle skutečných hodnot: 0.4 s / 34k buffers.
|
||||||
@@ -70,20 +84,6 @@ begin
|
|||||||
from slot_spine s
|
from slot_spine s
|
||||||
cross join tz t
|
cross join tz t
|
||||||
),
|
),
|
||||||
factor_raw as (
|
|
||||||
select ems.fn_pv_forecast_correction_factor(
|
|
||||||
%1$s,
|
|
||||||
(%4$L::timestamptz - (%9$s::text || ' hours')::interval)::timestamptz,
|
|
||||||
%4$L::timestamptz,
|
|
||||||
%10$s,
|
|
||||||
%11$s
|
|
||||||
) as j
|
|
||||||
),
|
|
||||||
factor as (
|
|
||||||
select
|
|
||||||
coalesce((j->>'correction_factor')::numeric, 1.0::numeric) as rolling_factor
|
|
||||||
from factor_raw
|
|
||||||
),
|
|
||||||
profile as (
|
profile as (
|
||||||
select ems.fn_pv_forecast_delta_profile_cached(
|
select ems.fn_pv_forecast_delta_profile_cached(
|
||||||
%1$s,
|
%1$s,
|
||||||
@@ -194,18 +194,17 @@ begin
|
|||||||
ab.pv_b_forecast_raw_w,
|
ab.pv_b_forecast_raw_w,
|
||||||
ab.pv_a_forecast_delta_w,
|
ab.pv_a_forecast_delta_w,
|
||||||
ab.pv_b_forecast_delta_w,
|
ab.pv_b_forecast_delta_w,
|
||||||
f.rolling_factor,
|
%13$s::numeric as rolling_factor,
|
||||||
case
|
case
|
||||||
when ab.interval_start < b.now_slot then 1.0::numeric
|
when ab.interval_start < b.now_slot then 1.0::numeric
|
||||||
when %12$s <= 0 then f.rolling_factor
|
when %12$s <= 0 then %13$s::numeric
|
||||||
else
|
else
|
||||||
case
|
case
|
||||||
when ((extract(epoch from (ab.interval_start - b.now_slot)) / 900)::int) >= %12$s then 1.0::numeric
|
when ((extract(epoch from (ab.interval_start - b.now_slot)) / 900)::int) >= %12$s then 1.0::numeric
|
||||||
else (1.0::numeric + (f.rolling_factor - 1.0::numeric) * (1.0::numeric - ((extract(epoch from (ab.interval_start - b.now_slot)) / 900)::numeric / %12$s::numeric)))
|
else (1.0::numeric + (%13$s::numeric - 1.0::numeric) * (1.0::numeric - ((extract(epoch from (ab.interval_start - b.now_slot)) / 900)::numeric / %12$s::numeric)))
|
||||||
end
|
end
|
||||||
end as rolling_effective_factor
|
end as rolling_effective_factor
|
||||||
from fc_ab ab
|
from fc_ab ab
|
||||||
cross join factor f
|
|
||||||
cross join bounds b
|
cross join bounds b
|
||||||
)
|
)
|
||||||
select coalesce(
|
select coalesce(
|
||||||
@@ -242,7 +241,8 @@ $q$,
|
|||||||
p_factor_window_h,
|
p_factor_window_h,
|
||||||
p_factor_min_clamp,
|
p_factor_min_clamp,
|
||||||
p_factor_max_clamp,
|
p_factor_max_clamp,
|
||||||
p_decay_slots
|
p_decay_slots,
|
||||||
|
v_rolling_factor
|
||||||
) into v_result;
|
) into v_result;
|
||||||
return coalesce(v_result, '[]'::jsonb);
|
return coalesce(v_result, '[]'::jsonb);
|
||||||
end;
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user