在我在 postgresql 中添加另一個過濾器后,我有一個功能完全失去了它的性能
這是一個簡單的例子,它最初的表現如何。
CREATE OR REPLACE FUNCTION my_function(param_a boolean, param_b boolean )
RETURNS TABLE(blablabla)
LANGUAGE sql
IMMUTABLE
AS $function$
with data as (
select id,amount,account_nr from transfer
)
select * from
data d
where param_a or 0.00 <> (select sum(d2.amount)
from data d2
where d2.id = d.id)
$function$
;
(cost=0.25..10.25 rows=1000 width=560)
(actual time=1162.528..1162.561 rows=306 loops=1)
Buffers: shared hit=1099180
Planning time: 2.928 ms
Execution time: 1162.630 ms
在我添加另一個帶有子選擇和計數的過濾器后,我失去了性能。這個計數對性能來說是否如此糟糕,我可以用另一種方式解決它嗎?
CREATE OR REPLACE FUNCTION my_function(param_a boolean, param_b boolean )
RETURNS TABLE(blablabla)
LANGUAGE sql
IMMUTABLE
AS $function$
with data as (
select id,amount,account_nr from transfer
)
select * from
data d
where (param_b or 1 < (select count(d2.account_nr)
from data d2
where d2.id = d.id
group by d2.account_nr))
and (param_a or 0.00 <> (select sum(d2.amount)
from data d2
where d2.id = d.id))
$function$
;
(cost=0.25..10.25 rows=1000 width=560)
(actualtime=271191.341..271191.383 rows=306 loops=1)
Buffers: shared hit=1099180
Planning time: 2.955 ms
Execution time: 271191.463 ms
uj5u.com熱心網友回復:
嵌入在存盤函式中的慢查詢是這樣的:
with data as ( -- original query from the question.
select id,amount,account_nr from transfer
)
select *
from data d
where (param_b or 1 < (select count(d2.account_nr)
from data d2
where d2.id = d.id
group by d2.account_nr)
)
and (param_a or 0.00 <> (select sum(d2.amount)
from data d2
where d2.id = d.id)
)
這有一個毫無意義的公用表運算式。為了簡單起見,我們可以擺脫它。如果您出于其他目的需要它,您可以隨時將其放回原處。
并且有幾個相關的子查詢。讓我們將它們重構為一個獨立的子查詢。從那個獨立的子查詢開始:
select id,
count(account_nr) account_count,
sum(amount) total_amount
from transfer
group by id
id此聚合子查詢生成表中每個帳戶的數量和總金額transfer。觀察結果以說服自己它可以滿足您的需求。
然后我們可以將其加入主查詢并應用您的 WHERE 條件。
select d.id, d.amount, d.account_nr
from transfer d
join (
select id,
count(account_nr) account_count,
sum(amount) total_amount
from transfer
group by id
) d2 ON d.id = d2.id
where (param_b or 1 < d2.account_count)
and (param_a or 0.00 <> d2.total_amount)
使用獨立的子查詢可以大大加快速度;有時查詢規劃器決定它需要多次重新評估相關子查詢。
以下索引將幫助子查詢運行得更快。
CREATE INDEX id_details ON transfer (id) INCLUDE (account_nr, amount);
說服自己這是可行的并且足夠快。(我沒有除錯它,因為我沒有你的資料。)你需要用 and 代替andtrue來false測驗它。param_aparam_b
然后,并且只有在那時,將其放入您的存盤函式中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/514367.html
上一篇:提高r中串列搜索功能的性能
下一篇:根據串列值從dict中檢索
