博客
关于我
oracle树形查询 start with connect by
阅读量:794 次
发布时间:2023-02-25

本文共 4140 字,大约阅读时间需要 13 分钟。

Oracle start with connect by 语句详解

1. 简介

在 Oracle 中,start with connect by (prior) 语句主要用于对具有树形结构的数据进行高效查询。该语句通过定义数据的搜索范围(start with)和递归查询条件(connect by),帮助用户快速定位所需数据。prior 关键字用于指定递归查询的方向,例如,当 prior 后面跟字段名时,它将用于查找子节点;当 prior 后面跟表达式时,则用于查找父节点。

例如,以下 SQL 语句可以查询 ID 为 '10001' 的记录,并递归查找其父节点和子节点:

start with id = '10001' connect by prior parent_id = id and prior num = 5

2. 实例

2.1 数据构造

为了更好地理解 start with connect by 的应用,我们首先需要创建一个具有树形结构的菜单数据表。以下是创建表格和初始化数据的 SQL 代码:

create table menu (
id varchar2(64) not null,
parent_id varchar2(64) not null,
name varchar2(100) not null,
depth number(2) not null,
primary key (id)
);
insert into menu values ('100000', '0', '顶级菜单1', 1);
insert into menu values ('200000', '0', '顶级菜单2', 1);
insert into menu values ('300000', '0', '顶级菜单3', 1);
insert into menu values ('110000', '100000', '菜单11', 2);
insert into menu values ('120000', '100000', '菜单12', 2);
insert into menu values ('130000', '100000', '菜单13', 2);
insert into menu values ('140000', '100000', '菜单14', 2);
insert into menu values ('210000', '200000', '菜单21', 2);
insert into menu values ('220000', '200000', '菜单22', 2);
insert into menu values ('230000', '200000', '菜单23', 2);
insert into menu values ('310000', '300000', '菜单31', 2);
insert into menu values ('131000', '130000', '菜单131', 3);
insert into menu values ('132000', '130000', '菜单132', 3);
insert into menu values ('133000', '130000', '菜单133', 3);
insert into menu values ('132100', '132000', '菜单1321', 4);
insert into menu values ('132200', '132000', '菜单1332', 4);

2.2 SQL 查询

2.2.1 查找父节点

以下 SQL 语句可以查找指定 ID 的父节点:

select * from menu start with id='130000' connect by id = prior.parent_id

2.2.2 查找子节点

以下 SQL 语句可以查找指定 ID 的所有子节点:

select * from menu start with id='130000' connect by prior.id = parent_id

2.2.3 查找叶子节点

以下 SQL 语句可以查询所有叶子节点(即没有子节点的节点):

select t2.* from menu t2 where t2.id not in (
select t.parent_id from menu t
) order by t2.id

2.2.4 统计层级关系

以下 SQL 语句可以统计每个菜单包含的子菜单数量:

select id, max(name) name, count(1) from menu group by id connect by prior.parent_id = id order by id

3. 性能优化

3.1 生成执行计划

为了优化 start with connect by 语句的性能,可以通过生成执行计划来分析查询的执行步骤。以下是生成执行计划的 SQL 代码:

explain plan for select * from menu start with id='132100' connect by prior.parent_id = id;

执行计划示例如下:

Plan hash value: 3563250490
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
|----|------------------------------|-------------|------|------|----------|---------|
| 0 | SELECT STATEMENT | | 1 | 133 | | 00:00:01 |
| | * 1 | CONNECT BY | | | | |
| | 2 | TABLE ACCESS BY INDEX ROWID | MENU | 1 | 133 | | 00:00:01 |
| | 3 | INDEX UNIQUE SCAN | SYS_C0018586 | 1 | | | 00:00:01 |
| | 4 | CONNECT BY PUMP | | | | | |
| | 5 | TABLE ACCESS BY INDEX ROWID | MENU | 1 | 133 | | 00:00:01 |
| | 6 | INDEX UNIQUE SCAN | SYS_C0018586 | 1 | | | 00:00:01 |
| | 7 | CONNECT BY PUMP | | | | | |
| | 8 | TABLE ACCESS BY INDEX ROWID | MENU | 1 | 133 | | 00:00:01 |
| | 9 | INDEX UNIQUE SCAN | SYS_C0018586 | 1 | | | 00:00:01 |
| | ... | | | | | |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ID"=PRIOR "PARENT_ID")
3 - access("ID"='132100')
7 - access("ID"=PRIOR "PARENT_ID")

3.2 优化建议

通过分析执行计划,可以看出 start with connect by 语句在数据量较大时可能导致性能问题。为了优化,可以考虑以下方法:

  • 减少递归深度:减少 connect by 子句中的递归深度,避免过深的递归查询。
  • 使用索引:确保菜单表的 id 字段有合适的索引,以提高查询效率。
  • 分批处理:对于大数据量的查询,可以考虑分批处理,减少一次性查询的压力。
  • 避免过滤:在 start with 子句中尽量避免条件过滤,减少对查询性能的负面影响。
  • 通过以上优化,可以显著提升 start with connect by 语句的执行效率,确保在大数据量下依然能够快速响应。

    转载地址:http://lepfk.baihongyu.com/

    你可能感兴趣的文章
    open-vm-tools-dkms : 依赖: open-vm-tools (>= 2:9.4.0-1280544-5ubuntu3) 但是它将不会被安装
    查看>>
    Openbox-桌面图标设置
    查看>>
    opencart出现no such file or dictionary
    查看>>
    opencv Mat push_back
    查看>>
    opencv waitKey() 函数理解及应用
    查看>>
    OpenCV 中的图像转换
    查看>>
    Opencv 完美配置攻略 2014 (Win8.1 + Opencv 2.4.8 + VS 2013)上
    查看>>
    opencv&Python——多种边缘检测
    查看>>
    opencv&python——高通滤波器和低通滤波器
    查看>>
    OpenCV-Python接口、cv和cv2的性能比较
    查看>>
    opencv12-图像金字塔
    查看>>
    opencv21-像素重映射
    查看>>
    opencv26-模板匹配
    查看>>
    opencv27-轮廓发现
    查看>>
    opencv29-轮廓周围绘制矩形框和圆形框
    查看>>
    OpenCV3 install tutorial for Mac
    查看>>
    opencv3-Mat对象
    查看>>
    opencv30-图像矩
    查看>>
    opencv32-基于距离变换和分水岭的图像分割
    查看>>
    opencv4-图像操作
    查看>>