oracle CONNECT BY NOCYCLE生成数百万个子节点

gg58donl  于 2023-05-22  发布在  Oracle
关注(0)|答案(1)|浏览(137)

我有一个数据库,其中from_nodeto_node是列。尝试查找从from_nodeto_node的所有可达节点。有循环。很少有from_node使用connect by nocycle,正在生成数百万个子节点。如何解决这一问题?

SELECT from_node,
       to_node,
       level
FROM PATH
START WITH from_node = input_var
CONNECT BY NOCYCLE PRIOR to_node= from_node;
zsbz8rwp

zsbz8rwp1#

根据您的描述,我可能会考虑使用递归子查询分解子句,而不是分层查询。这将更容易让你摆脱周期。这是因为NOCYCLE实际上并不停止周期,而是阻止Oracle关心它们。这是Oracle文档的摘录:
NOCYCLE参数指示Oracle数据库从查询中返回行,即使数据中存在CONNECT BY循环。将此参数与CONNECT_BY_ISCYCLE伪列沿着使用,以查看哪些行包含循环。有关详细信息,请参阅CONNECT_BY_ISCYCLE伪列。
像这样的递归子查询可能更适合你:

WITH path_search (from_node, to_node, path_level) AS
(
  SELECT p.from_node, p.to_node, 0 AS PATH_LEVEL
  FROM paths p
  WHERE p.from_node = 'A'
  UNION ALL
  SELECT p.from_node, p.to_node, ps.path_level+1 AS path_level
  FROM path_search ps
  INNER JOIN paths p ON ps.to_node = p.from_node
)
SEARCH DEPTH FIRST BY to_node SET order_col
CYCLE from_node SET is_cycle TO 'Y' DEFAULT 'N'
SELECT ps.from_node, ps.to_node, MIN(ps.path_level) AS MIN_DISTANCE
FROM path_search ps
WHERE is_cycle = 'N'
GROUP BY ps.from_node, ps.to_node
ORDER BY min_distance;

这里是一个SQLFiddle与此解决方案(链接)。
这将允许您在给定路径中检测到循环时停止递归。然而,由于在不同的路径上可以找到相同的路径段,因此仍然可能存在重复的往返节点,因此我添加了分组以仅显示最低级别,因为这是到达给定节点的最佳方式。

相关问题