4

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

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 使用量不断增加。
4

1 回答 1

2

所以问题与您的第二个选择语句有关,该语句需要与 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;
于 2016-05-10T14:52:01.340 回答