甲骨文嵌套的CONNECT BY子句导致性能不佳

问题描述 投票:1回答:1

下面的查询花费约一分钟。我相信表现不佳是由两个“IN(SELECT ...”的条款引起的。我有一个地方可以通过term_relationship表连接到另一个术语表。这些关系可以是递归的,例如,狗是一种类型的哺乳动物,哺乳动物是动物类型的,这递归可以是任何深度,但可能不会超过〜10级。我试图选择具有A型(潜在递归)关系的所有方面,并有一个(潜在的递归)的关系与B型。我认为,随着限制替换两个“IN(SELECT ...”的条款对外部查询会提高性能,但无法弄清楚如何使用CONNECT BY子句来做到这一点。任何人都可以在这方面帮助?

SELECT term_name
FROM term
WHERE term_id IN 
   (SELECT term_id 
    FROM term_relationship 
    START WITH related_term_id = 123
    CONNECT BY NOCYCLE PRIOR term_id = related_term_id)
AND term_id IN 
   (SELECT term_id 
    FROM term_relationship 
    START WITH related_term_id = 456
    CONNECT BY NOCYCLE PRIOR term_id = related_term_id)
oracle connect-by sql-subselect
1个回答
2
投票

相反,只有不同的初始值做同样的CONNECT BY查询两次的你怎么样通过提供做一次都开始值的子查询的一个实例。这一变化将让你的所有相关或者您的初始值的term_ids,但是,你想只有那些涉及到这两个起始值term_ids。为了得到这一点,你则需要组的结果通过term_id并限制具有多于一个的计数这些结果:

SELECT term_name
  FROM term
 WHERE term_id IN 
    (SELECT term_id 
       FROM term_relationship 
      START WITH related_term_id in (123, 456)
    CONNECT BY NOCYCLE PRIOR term_id = related_term_id
      group by term_id having count(*) >= 2)

编辑 与上面的代码我对你们数据的假设可能不正确。我以为树状结构,你用节点上的一个分支开始在图表A中向根向上行进等,然而,如果你的数据看起来像图B,那么上面的查询将如果你开始在节点7,9失败作为节点7具有两个路径回节点1,和上面的查询将返回节点1的两倍,从而正确地识别它作为一个公共节点。

A)   -(1)-                    B)   -(1)-
    /  |  \     (8)               /  |  \     (8)
  (2)  |  (3)    |              (2)  |  (3)    |
   |  (4)  |    (9)              |  (4)  |    (9)
  (5)     (6)                   (5)     (6)
           |                      \     /
          (7)                      -(7)-

下面的查询校正这一点,将正确地识别为起始然而节点7和9没有节点是共同的,与起始节点7和节点4 1被识别为公共节点:

SELECT term_name
  FROM term
 WHERE term_id IN 
    (SELECT term_id 
     FROM term_relationship 
    START WITH related_term_id in (123, 456)
  CONNECT BY NOCYCLE PRIOR term_id = related_term_id
    group by term_id
   having count(distinct connect_by_root related_term_id) >= 2)
© www.soinside.com 2019 - 2024. All rights reserved.