如何在 Oracle 11g 中查找给定父级的所有子 ID

Posted

技术标签:

【中文标题】如何在 Oracle 11g 中查找给定父级的所有子 ID【英文标题】:How to find all child ids given a parent in Oracle 11g 【发布时间】:2015-12-09 00:09:48 【问题描述】:

我有一个 id 表,它在不同的表中有一个 parentid,这在应用程序层中构建了一个文件夹结构。我需要获取特定“根文件夹”中所有 id 的列表

select count(id)
from t1, t2
where t1.id=t2.id
connect by prior t1.id = t2.parentid
start with t1.id in (select id from t3 where name = 'Root Folder')

t1 = 4,102,065 行

t2 = 48,965,392 行

t3 是一个视图

t4是存储t3中名称的底层表(仅在下面的解释计划中引用)

现在这是返回正确的结果,但需要 3 分 41 秒(计数为 3,257,847)

有没有更好的方法来做这种类型的查询或者是我唯一的选项索引?

这是解释计划,我已经替换了真实的表和索引名称以匹配我上面的示例:

Plan
SELECT STATEMENT  ALL_ROWSCost: 14  Bytes: 20  Cardinality: 1                                   
17 SORT GROUP BY  Bytes: 20  Cardinality: 1                                 
    16 CONNECT BY WITH FILTERING                            
        10 NESTED LOOPS  Cost: 5  Bytes: 153  Cardinality: 3                        
            8 NESTED LOOPS  Cost: 4  Bytes: 27  Cardinality: 1                      
                6 VIEW VIEW SYS.VW_NSO_1 Cost: 2  Bytes: 10  Cardinality: 1                 
                    5 HASH UNIQUE  Bytes: 57  Cardinality: 1            
                        4 NESTED LOOPS  Cost: 2  Bytes: 57  Cardinality: 1          
                            2 TABLE ACCESS BY INDEX ROWID TABLE T2 Cost: 1  Bytes: 40  Cardinality: 1   
                                1 INDEX RANGE SCAN INDEX T2_NAME Cost: 1  Cardinality: 1  
                            3 INDEX UNIQUE SCAN INDEX (UNIQUE) T3_ID Cost: 1  Bytes: 17  Cardinality: 1     
                7 INDEX UNIQUE SCAN INDEX (UNIQUE) T1_ID Cost: 1  Bytes: 17  Cardinality: 1                 
            9 INDEX RANGE SCAN INDEX T2_ID_PARENTID Cost: 1  Bytes: 72  Cardinality: 3                      
        15 NESTED LOOPS  Cost: 7  Bytes: 867  Cardinality: 17                       
            13 NESTED LOOPS  Cost: 6  Bytes: 1,292  Cardinality: 38                     
                11 CONNECT BY PUMP                  
                12 INDEX RANGE SCAN INDEX T2_PARENTID_ID Cost: 1  Bytes: 312  Cardinality: 13               
            14 INDEX UNIQUE SCAN INDEX (UNIQUE) T1_ID Cost: 1  Bytes: 17  Cardinality: 1                    

【问题讨论】:

解释计划可以帮助我们理解问题。运行explain plan for select count(id) ... 生成计划,然后运行它来显示计划:select * from table(dbms_xplan.display);。在此处打印整个输出。 从你最后一句话的语气看来,你可能索引是个坏主意。为什么会这样? 你的查询很简单,尝试使用带索引的查询提示 @jon-heller 我已经添加了解释计划。 @bob-jarvis 不,一点也不,只是我想让它在我必须要求 DBA 创建索引之前尽可能地发挥作用 【参考方案1】:

您唯一的选择是在 t1.id 和 t2.parentid 上创建索引,并确保通过分析执行计划来使用这些索引,并在出现这种情况时使用提示。还要注意为 t1、t2 及其索引提供新的性能统计信息。

【讨论】:

以上是关于如何在 Oracle 11g 中查找给定父级的所有子 ID的主要内容,如果未能解决你的问题,请参考以下文章

swift Core Data谓词过滤给定父级的所有子数据

具有多个父级的 Oracle 分层查询

linux 怎么查找oracle11g的安装目录

从混合层级中查找多个子级的第一个共同父级

linux 怎么查找oracle11g的安装目录

如何在 Oracle 11g 中使用列名查找存储过程的名称