【问题标题】:Infinite loop in H2 queryH2查询中的无限循环
【发布时间】:2016-09-05 15:02:57
【问题描述】:

我正在通过使用JUnit 运行的测试在具有 3 个条目的表上对 H2 database 执行以下查询:

WITH ancestors(ID, PARENT_ID) AS 
(
  SELECT ID, PARENT_ID FROM PEOPLE WHERE ID = <person_id>
    UNION ALL
  SELECT P1.ID, P1.PARENT_ID FROM PEOPLE P1, PEOPLE P2 WHERE P1.ID = P2.PARENT_ID
)
SELECT ID FROM ancestors;

查询在包含人员的自引用表上执行。它找到一个人的所有祖先的 id。

由于某种原因,这会在测试挂起时运行我猜想是一个无限循环,并且我可以看到 RAM 使用量迅速上升 (>2GB)。 为什么会发生这种情况,我该如何解决?

观察:

  • 这在 Oracle 中执行良好
  • 如果表中没有指定 PARENT_ID,它会正常执行,但如果有,它会挂起并且 RAM 使用量不断增加。

【问题讨论】:

    标签: sql infinite-loop h2 hierarchical-data hierarchical-query


    【解决方案1】:

    所以问题与您的第二个选择语句有关,该语句需要与 CTE acenstors 表相关

    所以根据我的查询,它在做什么

    1) 所以第一个查询将添加起始节点并执行一次。例如,ID="John"、Parent_ID="Rob"

    2) 将执行多次的第二个查询将查找人员 ID="Rob",因为我们要加入“ON P1.PARENT_ID = P2.ID”。例如)这将添加 [ID="ROB", Parent_ID="Susan"] 和 ID="ROB", Parent_ID="Paul"]

    3) 在幕后,它会再次执行第 2 步,这次它会查找人名 Susan 和 Paul,并将其添加到祖先表中。这样做直到它不再返回任何记录。

    WITH ancestors(ID, PARENT_ID) AS 
    (
        --child
        SELECT 
            ID, 
            PARENT_ID 
        FROM PEOPLE 
        WHERE ID = <person_id>
    
        UNION ALL
    
        --get my lineage
        SELECT 
            P2.ID, 
            P2.PARENT_ID 
        FROM ancestors P1 
        INNER JOIN PEOPLE P2 
            ON P1.PARENT_ID = P2.ID
    )
    SELECT ID FROM ancestors;
    

    【讨论】:

    • 第二次选择肯定会返回 P1。我尝试更改为 INNER JOIN 而不是 WHERE 但这没有区别。
    • 糟糕。我的查询出错了。您的第二个查询应该加入 CTE 表“祖先”,它应该返回 P2 值。否则,您将拥有相同的根节点。
    • 我也试过了,它只返回 值(​​即没有祖先)。
    • Opps 我的代码得到了子树。我已经更新了代码。您只需要更改联接。
    • 太好了,成功了,谢谢!请添加更多信息,说明导致无限循环的原因以及您的答案修复它的原因,我会奖励它:)
    猜你喜欢
    • 1970-01-01
    • 2011-07-25
    • 2016-01-02
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2022-08-17
    • 2020-06-30
    相关资源
    最近更新 更多