始创于2000年 股票代码:831685
咨询热线:0371-60135900 注册有礼 登录
  • 挂牌上市企业
  • 60秒人工响应
  • 99.99%连通率
  • 7*24h人工
  • 故障100倍补偿
您的位置: 网站首页 > 帮助中心>文章内容

Oracle 树查询 性能优化纪实(start with, connect by)

发布时间:  2012/8/21 17:00:06

在项目中做权限控制时,需要用组织阶层来控制能够访问的数据,
比如A组织的人可以看到其下属组织的人员数据,或者只有A组织是B组织上级的时候才有看B组织人员数据的权利。
根据需求需要构筑DB的表结构,如下(ORG_RANK)

组织ID(PK) 上位组织ID
ORG_ID HIGH_ORG_ID

根据上面的结构,使用Oracle的树查询语句(start with和connect by)来创建SQL语句,如下:

-

 

查询指定组织的直属下层组织:

Sql代码   
select  ORANK.ORG_ID  
  from  ORG_RANK ORANK  
where  ( level  - 1) = 1  
start with  ORANK.ORG_ID = #orgId#  
connect   by   prior  ORANK.ORG_ID = ORANK.HIGH_ORG_ID  
select ORANK.ORG_ID
  from ORG_RANK ORANK
where (level - 1) = 1
start with ORANK.ORG_ID = #orgId#
connect by prior ORANK.ORG_ID = ORANK.HIGH_ORG_ID对以上SQL做性能评定时发现出现严重性能问题,(10层组织,3000条数据时)查询时间1分多钟,下面进行了优化。

1、分析执行计划,发现有Full Table,说明使用索引失败,优化的方法是对HIGH_ORG_ID加上索引。

2、虽然只是查询直属下层的组织,但是上面SQL实际执行时,先查询出指定组织的所有下层组织,

然后再从结果里过滤出直属下层的组织(where (level - 1) = 1)。

上面的分析可以得到证明,因为输入倒数第二层组织的执行时间会比输入最上层组织的执行时间少的多。

优化方法是增加connect by语句的条件(and (level - 1) <= 1),不满足条件的子树不会被查询,会省去很多没用的递归查询。

Sql代码   
select  ORANK.ORG_ID  
  from  ORG_RANK ORANK  
where  ( level  - 1) = 1  
start with  ORANK.ORG_ID = #orgId#  
connect   by   prior  ORANK.ORG_ID = ORANK.HIGH_ORG_ID  
and  ( level  - 1) <= 1  
select ORANK.ORG_ID
  from ORG_RANK ORANK
where (level - 1) = 1
start with ORANK.ORG_ID = #orgId#
connect by prior ORANK.ORG_ID = ORANK.HIGH_ORG_ID
and (level - 1) <= 1判断组织A是组织B的上层组织:

方法一:查询出A的所有下层组织,看其中是否有B;

方法二:查询出B的所有上层组织,看其中是否有A。

只要你头脑里自己描绘出一个树型的组织结构,那么你自然会想到方法二的执行速度会明显比方法一块,

方法二是逆行查询,查到的数据量小。


本文出自:亿恩科技【www.enkj.com】

-

 

查询指定组织的直属下层组织:

Sql代码   
select  ORANK.ORG_ID  
  from  ORG_RANK ORANK  
where  ( level  - 1) = 1  
start with  ORANK.ORG_ID = #orgId#  
connect   by   prior  ORANK.ORG_ID = ORANK.HIGH_ORG_ID  
select ORANK.ORG_ID
  from ORG_RANK ORANK
where (level - 1) = 1
start with ORANK.ORG_ID = #orgId#
connect by prior ORANK.ORG_ID = ORANK.HIGH_ORG_ID对以上SQL做性能评定时发现出现严重性能问题,(10层组织,3000条数据时)查询时间1分多钟,下面进行了优化。

1、分析执行计划,发现有Full Table,说明使用索引失败,优化的方法是对HIGH_ORG_ID加上索引。

2、虽然只是查询直属下层的组织,但是上面SQL实际执行时,先查询出指定组织的所有下层组织,

然后再从结果里过滤出直属下层的组织(where (level - 1) = 1)。

上面的分析可以得到证明,因为输入倒数第二层组织的执行时间会比输入最上层组织的执行时间少的多。

优化方法是增加connect by语句的条件(and (level - 1) <= 1),不满足条件的子树不会被查询,会省去很多没用的递归查询。

Sql代码   
select  ORANK.ORG_ID  
  from  ORG_RANK ORANK  
where  ( level  - 1) = 1  
start with  ORANK.ORG_ID = #orgId#  
connect   by   prior  ORANK.ORG_ID = ORANK.HIGH_ORG_ID  
and  ( level  - 1) <= 1  
select ORANK.ORG_ID
  from ORG_RANK ORANK
where (level - 1) = 1
start with ORANK.ORG_ID = #orgId#
connect by prior ORANK.ORG_ID = ORANK.HIGH_ORG_ID
and (level - 1) <= 1判断组织A是组织B的上层组织:

方法一:查询出A的所有下层组织,看其中是否有B;

方法二:查询出B的所有上层组织,看其中是否有A。

只要你头脑里自己描绘出一个树型的组织结构,那么你自然会想到方法二的执行速度会明显比方法一块,

方法二是逆行查询,查到的数据量小。


本文出自:亿恩科技【www.enidc.com】
-->

服务器租用/服务器托管中国五强!虚拟主机域名注册顶级提供商!15年品质保障!--亿恩科技[ENKJ.COM]

  • 您可能在找
  • 亿恩北京公司:
  • 经营性ICP/ISP证:京B2-20150015
  • 亿恩郑州公司:
  • 经营性ICP/ISP/IDC证:豫B1.B2-20060070
  • 亿恩南昌公司:
  • 经营性ICP/ISP证:赣B2-20080012
  • 服务器/云主机 24小时售后服务电话:0371-60135900
  • 虚拟主机/智能建站 24小时售后服务电话:0371-60135900
  • 专注服务器托管17年
    扫扫关注-微信公众号
    0371-60135900
    Copyright© 1999-2019 ENKJ All Rights Reserved 亿恩科技 版权所有  地址:郑州市高新区翠竹街1号总部企业基地亿恩大厦  法律顾问:河南亚太人律师事务所郝建锋、杜慧月律师   京公网安备41019702002023号
      0
     
     
     
     

    0371-60135900
    7*24小时客服服务热线