oracle樹形查詢 start with connect by
一、簡介
在oracle中start with connect by (prior) 用來對樹形結構的數據進行查詢。其中start with conditon 給出的是數據搜索範圍, connect by後面給出了遞歸查詢的條件,prior 關鍵字表示父數據,prior 條件表示子數據需要滿足父數據的什麼條件。如下
start with id= '10001' connect by prior parent_id= id and prior num = 5
表示查詢id爲10001,並且遞歸查詢parent_id=id,爲5的記錄。
二、實例
1、構造數據
生成的菜單層次結構如下:
頂級菜單1
菜單11
菜單12
菜單13
菜單131
菜單132
菜單1321
菜單1322
菜單133
菜單14
頂級菜單2
菜單21
菜單22
菜單23
頂級菜單3
菜單31
2、SQL查詢
--prior放的左右位置決定了檢索是自底向上還是自頂向下. 左邊是自上而下(找子節點),右邊是自下而上(找父節點) --找父節點 select * from menu start with id='130000' connect by id = prior parent_id;
--找子節點節點 -- (子節點)id爲130000的菜單,以及130000菜單下的所有直接或間接子菜單(prior 在左邊, prior、parent_id(等號右邊)在右邊) select * from menu start with id='130000' connect by prior id = parent_id ;
-- (父節點)id爲1321的菜單,以及1321菜單下的所有直接或間接父菜單(prior、parent_id(等號左邊) 都在左邊) select * from menu start with id='132100' connect by prior parent_id = id; -- prior 後面跟的是(parent_id) 則是查找父節點,prior後面跟的是(id)則是查找子節點
--根據菜單組分類統計每個菜單包含子菜單的個數 select id, max(name) name, count(1) from menu group by id connect by prior parent_id = id order by id
-- 查詢所有的葉子節點 select t2.* from menu t2 where id not in(select t.parent_id from menu t) order by id;
三、性能問題
對於 start with connect by語句的執行,oracle會進行遞歸查詢,當數據量大的時候會產生性能相關問題。
--生成執行計劃 explain plan for select * from menu start with id='132100' connect by prior parent_id = id;
– 查詢執行計劃
select * from table( dbms_xplan.display);
語句執行計劃結果如下:
Plan hash value: 3563250490
–--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
–--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 133 | 1 (0)| 00:00:01 |
| 1 | CONNECT BY WITH FILTERING | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID | MENU | 1 | 133 | 1 (0)| 00:00:01 |
| 3 | INDEX UNIQUE SCAN | SYS_C0018586 | 1 | | 1 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | | | | |
| 5 | CONNECT BY PUMP | | | | | |
| 6 | TABLE ACCESS BY INDEX ROWID| MENU | 1 | 133 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | SYS_C0018586 | 1 | | 1 (0)| 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”)
Note
–—
- dynamic sampling used for this statement
通過該執行計劃得知,改語句執行了7步操作,纔將結果集查詢並返回。當需要查詢條件進行過濾的時候,我們可以通過查看執行計劃從而對sql進行優化。
<p class="postfoot">
posted on <span id="post-date">2015-10-30 16:16</span> <a href="https://www.cnblogs.com/always-online/">煙火_</a> 閱讀(<span id="post_view_count">19123</span>) 評論(<span id="post_comment_count">1</span>) <a href="https://i.cnblogs.com/EditPosts.aspx?postid=4923532" rel="nofollow">編輯</a> <a href="#" onclick="AddToWz(4923532);return false;">收藏</a>
</p>
</div>
<script type="text/javascript">var allowComments=true,cb_blogId=170201,cb_entryId=4923532,cb_blogApp=currentBlogApp,cb_blogUserGuid='14500b3b-0358-e311-8d02-90b11c0b17d6',cb_entryCreatedDate='2015/10/30 16:16:00';loadViewCount(cb_entryId);var cb_postType=1;</script>
</div>