关于递归 SQL 查询,它们的性能和无限递归
About Recursive SQL queries, their performance and Infinite recursion
我想构建一个 "recursive" 查询以在我的 PostgreSQL 数据库上使用,这个想法和您想象的一样基本:)
SELECT sourceid, destinationid FROM trail.log
WHERE sourceid = 'T0'
OR sourceid in (SELECT destinationid FROM trail.log where sourceid ='T0')
OR sourceid in (SELECT destinationid FROM trail.log where sourceid in ( you see where I want to go ... )
OR ...
根据互联网,这是我应该做的:
WITH cte_traillog AS (
SELECT
sourceid, destinationid
FROM
trail.log
WHERE sourceid = 'T0'
UNION ALL
SELECT
e.sourceid, e.destinationid
FROM
trail.log e
INNER JOIN cte_org o
ON o.destinationid = e.sourceid
)
SELECT * FROM cte_traillog;
知道第一个查询在我的服务器上不到一分钟就会回复,第二个查询是否具有相同的性能?
(下面是一些可能很愚蠢的问题)
如果我的第一个查询没有造成太大麻烦,那么第二个查询是否会导致服务器崩溃?
如果数据会造成死循环怎么办?
有没有办法防止无限循环?
更一般地说,这是正确的方法吗?
提前感谢您的宝贵时间。
祝你有美好的一天。
您的查询有误:您在递归分支中引用 CTE 时使用了错误的名称。除此之外,您的查询看起来没问题。
查询的 运行 时间将取决于层次结构的深度,即 "recursive"(实际上:迭代)部分执行的频率。索引可以使它非常快。
如果层级包含循环,递归将永远不会停止,最终会出现堆栈溢出错误。为防止出现这种情况,您可以使用 UNION
而不是 UNION ALL
,这将消除重复项。
我想构建一个 "recursive" 查询以在我的 PostgreSQL 数据库上使用,这个想法和您想象的一样基本:)
SELECT sourceid, destinationid FROM trail.log
WHERE sourceid = 'T0'
OR sourceid in (SELECT destinationid FROM trail.log where sourceid ='T0')
OR sourceid in (SELECT destinationid FROM trail.log where sourceid in ( you see where I want to go ... )
OR ...
根据互联网,这是我应该做的:
WITH cte_traillog AS (
SELECT
sourceid, destinationid
FROM
trail.log
WHERE sourceid = 'T0'
UNION ALL
SELECT
e.sourceid, e.destinationid
FROM
trail.log e
INNER JOIN cte_org o
ON o.destinationid = e.sourceid
)
SELECT * FROM cte_traillog;
知道第一个查询在我的服务器上不到一分钟就会回复,第二个查询是否具有相同的性能? (下面是一些可能很愚蠢的问题) 如果我的第一个查询没有造成太大麻烦,那么第二个查询是否会导致服务器崩溃? 如果数据会造成死循环怎么办? 有没有办法防止无限循环? 更一般地说,这是正确的方法吗?
提前感谢您的宝贵时间。
祝你有美好的一天。
您的查询有误:您在递归分支中引用 CTE 时使用了错误的名称。除此之外,您的查询看起来没问题。
查询的 运行 时间将取决于层次结构的深度,即 "recursive"(实际上:迭代)部分执行的频率。索引可以使它非常快。
如果层级包含循环,递归将永远不会停止,最终会出现堆栈溢出错误。为防止出现这种情况,您可以使用 UNION
而不是 UNION ALL
,这将消除重复项。