Postgresql

強制執行一次穩定的 postgres 函式

  • June 16, 2022

我為多個表 ID 組合創建了一個命名函式,以供人類理解。本質上,它將重要數據組合成 varchar 的表非規範化。

它需要 3 個參數,並且是一個穩定的函式,但我無法讓我的觀點來使用它。當我的視圖返回 10k 個結果時,每行都有相同的 3 個輸入值……它執行函式 10000 次,使查詢花費 100 倍的時間。

我的函式並不意味著要快,但大概是查詢計劃,數據庫認為這樣會更快(我有交叉連接和視窗聚合等)

我嘗試將查詢的其餘部分放入內部查詢中,將我的函式放入橫向連接中,並將函式成本增加到數百萬,但都是徒勞的。

有沒有辦法暗示它是(記憶體的)執行(除了我已經嘗試過的),或者一些會使 postgres 忽略穩定聲明的因素(參數太多)?

如果您認為查詢優化器出錯了,那麼使用 PL/pgSQL 語言逐步進行查詢可能會有所幫助。您可以使用變數記憶體函式結果。

create function f1(<...>) returns <type> as $body$
declare
 A int;
begin
 select stable_func() into A;
 <...>
end $body$ language 'plpgsql';

PostgreSQL 文件為任何人學習這門語言提供了很好的材料:

https://www.postgresql.org/docs/current/plpgsql.html

大幅增加功能成本通常會使計劃者從它考慮的所有計劃的範圍中選擇它認為對功能評估最少的計劃。但這不會導致規劃者考慮原本不會考慮的計劃。您無法進行任何秘密設置來更改此設置,它需要規劃器中的新程式碼。

我嘗試將查詢的其餘部分放入內部查詢中,將我的函式放入橫向連接中,並將函式成本增加到數百萬,但都是徒勞的

內部查詢通常可以工作,但不知道你具體做了什麼……

例如,這可以將 foo(4) 的呼叫次數從 15 減少到 1。

create table t as select f,4 a from generate_series(1,15) f(f);

select f, a2 from (select a, foo(a) as a2 from t group by a) distincta join t using (a);

引用自:https://dba.stackexchange.com/questions/313416