我有一個很大的 postgres 查詢,其中包含很多我想過濾幾種不同方式的連接。我有一個執行連接的中心函式:
create function my_big_function(p_limit int, p_offset, p_filter_ids int[])
returns setof my_type
language sql
immutable
returns null on null input
as
$$
select my_column_list
from
(
select my_filter_id
from unnest(p_filter_ids)
order by my_filter_id
limit p_limit, offset p_offset
) f(my_filter_id)
inner join... several other tables (using indexed columns)
然后我有一系列用于構建過濾器 ID 串列的簡短函式,例如:
create or replace my_filter_id_function(p_some_id int)
returns int[]
language sql
immutable
returns null on null input
as
$$
select array_agg(my_filter_id) from my_table where some_id = p_some_id
$$;
這使我可以快速添加幾個過濾器函式并將結果陣列作為引數輸入到大查詢中,而不必在很多地方復制大查詢。
select * from my_big_function(1000, 0, my_filter_function1(p_some_id));
select * from my_big_function(1000, 0, my_filter_function2(p_some_other_id));
select * from my_big_function(1000, 0, my_filter_function3(p_yet_another_id));
問題是當過濾器函式回傳的值陣列變大(約 1,000 行)時,我的查詢速度很慢。我認為這是因為大查詢必須先排序然后使用非索引結果加入?有沒有更好的方法來擁有一個通用查詢,我可以將 ID 輸入以不同的方式過濾它?
uj5u.com熱心網友回復:
我會避免使用大型陣列,因為打包和解包它們會變得很昂貴。
但我想說這里的主要問題是您將查詢拆分為不同的函式,這會阻止優化器一次處理整個查詢并得出一個有效的執行計劃。
如果您想避免一遍又一遍地重復查詢的某些部分,正確的工具不是函式,而是視圖。執行查詢時,視圖會被其定義替換,因此優化器可以為整個查詢找到一個好的計劃。
不要陷入定義連接所有表格的“世界觀”的陷阱。該視圖應該只包含您在查詢中實際需要的表。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/420777.html
標籤:
上一篇:求最小代價組合演算法
