我在Postgres中编写了一个存储过程,它接受两个整数参数作为输入。
CREATE OR REPLACE FUNCTION public.tickets_long_open(comp_id integer, days integer, ref refcursor)
RETURNS refcursor
AS $$
begin
open ref for
select q.svc_ord_nbr, q.po_nbr, q.state, q.city, q.cust_name, q.days_open, q.status
from
(select a.svc_ord_nbr, a.po_nbr, a.create_dtm,
b.sap_sls_org_name, b.cust_lvl_2_name,
d.close_dtm, d.debit_memo_dtm,
l.state, l.city, l.cust_name,
date_part('day', (select case when d.close_dtm is null then now() else d.close_dtm end close_ts) - a.create_dtm) as days_open,
case when d.close_dtm is null and d.debit_memo_dtm is null then 'OPEN' else 'CLOSED' end status
from dmt_mas_svc_ord_fact a
inner join dmt_mas_cust_dim b on a.shipto_cust_id = b.cust_id
inner join dmt_mas_svc_ord_degen_dim d on a.svc_ord_id = d.svc_ord_id
inner join store_location l on b.cust_name = l.cust_name
where b.sap_sls_org_name like '%US%'
and a.create_dtm >= now() - interval '12 months'
and l.company_id = comp_id) q
where q.days_open > days
order by q.state, q.city, q.cust_name;
return ref;
end;
$$ language plpgsql;
为了显示结果集,我将cursor作为第三个参数包含在内,这样我就可以运行以下内容来获取光标:
begin;
select tickets_long_open(1, 30, 'refc');
fetch all in "refc";
返回88行记录需要26分钟。
如果我删除前两个参数comp_id
和days
并在查询中对其进行硬编码。 select tickets_long_open('refc')
的抓取只需19秒。其他一切都是一样的。
为什么在我有两个参数时需要很长时间来获取结果集?为什么删除参数会突然变得更快?
修改: 在一些调试之后,事实证明只有在运行时获取输入变量时查询才会变慢。将它作为表返回不会改变任何东西。将函数更改为普通sql无济于事
CREATE OR REPLACE FUNCTION public.tickets_long_open(comp_id integer, days double precision)
RETURNS TABLE(svc_ord_nbr text, po_nbr text, state text, city text, cust_name text, days_open double precision, status text)
AS $$
select q.svc_ord_nbr, q.po_nbr, q.state, q.city, q.cust_name, q.days_open, q.status
from
(select a.svc_ord_nbr, a.po_nbr, a.create_dtm,
b.sap_sls_org_name, b.cust_lvl_2_name,
d.close_dtm, d.debit_memo_dtm,
l.state, l.city, l.cust_name,
date_part('day', (select case when d.close_dtm is null then now() else d.close_dtm end close_ts) - a.create_dtm) as days_open,
case when d.close_dtm is null and d.debit_memo_dtm is null then 'OPEN' else 'CLOSED' end status
from dmt_mas_svc_ord_fact a
inner join dmt_mas_cust_dim b on a.shipto_cust_id = b.cust_id
inner join dmt_mas_svc_ord_degen_dim d on a.svc_ord_id = d.svc_ord_id
inner join store_location l on b.cust_name = l.cust_name
where b.sap_sls_org_name like '%US%'
and a.create_dtm >= now() - interval '12 months'
and l.company_id = comp_id) q
where q.days_open > days
order by q.state, q.city, q.cust_name;
end;
$$ language sql stable;