我有一个函数,该函数采用organization_ids
数组,然后递归枚举这些组织的员工层次结构树。它由organization_ids
参数化,因此此函数的调用者只能请求他们需要的信息,因为使用非参数化的递归视图将非常昂贵。
该函数非常简单,看起来像这样:
create or replace function manager_hierarchy (variadic organization_ids int[])
returns table(organization_id int, employee_id int, managers_above_ids int[]) as $$
with recursive filtered_manager_assignments as (
select a.manager_id, a.employee_id
from manager_assignments a
inner join employees e on e.id = a.employee_id and e.organization_id in (select unnest(organization_ids))
where a.effective_date_range @> current_date
),
hierarchy(organization_id, employee_id, managers_above_ids) as (
select e.organization_id, e.id, array[]::integer[]
from employees e
where e.organization_id in (select unnest(organization_ids))
and e.id not in (select employee_id from filtered_manager_assignments)
union all
select h.organization_id, a.employee_id, array_append(h.managers_above_ids, a.manager_id)
from hierarchy h
inner join filtered_manager_assignments a on a.manager_id = h.employee_id
)
select * from hierarchy;
$$ LANGUAGE SQL STABLE COST 100000;
该函数本身是相当有效的,但是我很难设计一种策略以在视图的上下文中有效地应用它。我将其嵌入的视图的定义非常复杂,但是一个简单的示例也可以用来说明我的困难:
create view v_employees (
select e.organization_id, concat(e.first_name, ' ', e.last_name) name, h.managers_above_ids
from employees e
inner join manager_hierarchy(e.organization_id) h on h.employee_id = e.id
);
由于视图的每一行都会调用manager_hierarchy
函数,因此该视图的查询速度将非常慢。我可以将函数调用的结果存储在CTE中,但这不能使用organization_ids
函数的manager_hierarchy
自变量来仅提取所需的内容。例如,如果视图的用户执行select * from v_employees where organization_id = 1
,则在CTE上下文中我无法知道仅使用参数manager_hierarchy
来调用1
。 / p>
在理想状态下,我将能够执行主查询视图,然后仅在主查询结果中存在manager_hierarchy
的情况下调用organization_id
,最后添加相关的层次结构信息到视图的每一行。我似乎无法想到一种在视图上下文中完成此特定工作流的方法。我考虑过但想避免的其他想法是,创建一个物化视图来存储所有组织的层次结构信息,或者使用临时表来记录manager_hierarchy
的结果。
如何最好地改善此视图的性能?