oracle樹形查詢 start with connect by

原文

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、構造數據

按 Ctrl+C 複製代碼
按 Ctrl+C 複製代碼

  生成的菜單層次結構如下:
頂級菜單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進行優化。

 

分類: 數據庫
4
0
« 上一篇:mybatis oracle BLOB類型字段保存與讀取
» 下一篇:oracle行轉列與列轉行
	<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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章