jul*_*icz 14 database postgresql recursive-query with-statement
我有一个简单的问题.不知怎的,我无法找到明确的答案.
有多少是WITH RECURSIVE
语法PostgreSQL的优化?我的意思是:它仅仅是一系列非递归查询的语法糖,或者它是一个单一的语句,尽管其复杂的语义已经作为一个整体进行了优化.一个后续问题 - 关于优化这种语法的可能性有多大?当然,非常欢迎有关此事的一些具体数据.
Den*_*rdy 19
我发现它已经优化到一定程度.
各种子查询按预期重复使用并单独优化,Postgres就像任何其他查询一样优化后者.
我对它的主要抱怨是它不会在可能的情况下向CTE注入限制.
例如:
with recursive
parents as (
select node.id,
node.parent_id
from nodes as node
union all
select node.id,
parent.parent_id
from parents as node
join nodes as parent on parent.id = node.parent_id
)
select parent_id
from parents
where id = 2;
Run Code Online (Sandbox Code Playgroud)
Postgres的理想地理解,在上面的,是(因为node.id返回原样),它可以这样做:
with recursive
parents as (
select node.id,
node.parent_id
from nodes as node
where id = 2
union all
select node.id,
parent.parent_id
from parents as node
join nodes as parent on parent.id = node.parent_id
)
select parent_id
from parents;
Run Code Online (Sandbox Code Playgroud)
...并在主键上使用索引扫描.在实践中,它实际上确实在CTE告诉它做的时候:递归地拉出所有行的所有父项,如果需要,将结果集放在一个未命名的临时表中,然后检查结果集中的每一行为id = 2.
换句话说,CTE不会跟踪它返回的"原始"表/行/列集.在正确优化之前,在递归查询上创建视图充其量是疯狂的.
同时一个好的解决方法是创建一个sql函数:
create function parents(id int) as returns table (id int) $$
with recursive
parents as (
select node.id,
node.parent_id
from nodes as node
where id = $1
union all
select node.id,
parent.parent_id
from parents as node
join nodes as parent on parent.id = node.parent_id
)
select parent_id
from parents;
$$ language sql stable strict rows 5 cost 1;
Run Code Online (Sandbox Code Playgroud)
另一个问题是你不能使用FOR UPDATE和递归CTE(事实上,出于同样的原因).
小智 6
我的经验是,它确实优化得很好。
检查由 EXPLAIN ANALYZE 生成的查询的执行计划,您将看到它到底有多么“昂贵”(然后将其与自编写的递归函数进行比较)
归档时间: |
|
查看次数: |
9097 次 |
最近记录: |