關於迴圈巢狀nested loops的一點分析
nested loops連線 /*+use_nl(tab01 tab02)*/
迴圈巢狀連線:oracle最佳化器根據基於rbo和cbo原則,選擇兩個表中一個為驅動表,也就是外部表,另一個作為內部表。注意hint寫法中表如果用的別名,hint中必須寫相應的別名,不然相應的hint不能生效。
在oracle9I後最佳化器推出兩種執行方式,方式1先從外部表取第一行然後和內部表資料進行比較,此時會逐行取出資料,重複上述步驟直到外部表中所有記錄全部處理完畢。
SQL> desc tab01;
Name Type Nullable Default Comments
---- ------------ -------- ------- --------
ID NUMBER Y
NAME VARCHAR2(10) Y
SQL> desc tab02;
Name Type Nullable Default Comments
---- ------------ -------- ------- --------
ID NUMBER Y
NAME VARCHAR2(10) Y
SQL> explain plan for select a.id,b.name from tab01 a,tab02 b
2 where a.id=b.id;
Explained
SQL> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3710181165
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 3300 | 2 (0)| 00:00:01
| 1 | NESTED LOOPS | | 100 | 3300 | 2 (0)| 00:00:01
| 2 | TABLE ACCESS FULL| TAB02 | 100 | 2000 | 2 (0)| 00:00:01
|* 3 | INDEX RANGE SCAN | INDEX_TAB01 | 1 | 13 | 0 (0)| 00:00:01
方式2 也是先從外部表取第一行然後和內部表資料進行比較,此時會記錄內部表上相應的rowid,但是不會馬上去內部表上取出資料,此時會繼續從外部表繼續取第二行資料然後獲取rowid,直到所有資料獲取完畢後,再對內部表進行索引掃描。
SQL> explain plan for select a.id,a.name,b.name from tab01 a,tab02 b where a.id=b.id
;
2 /
Explained
SQL> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1970217900
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 4000 | 3 (0)|
| 1 | TABLE ACCESS BY INDEX ROWID| TAB02 | 1 | 20 | 1 (0)|
| 2 | NESTED LOOPS | | 100 | 4000 | 3 (0)|
| 3 | TABLE ACCESS FULL | TAB01 | 100 | 2000 | 2 (0)|
|* 4 | INDEX RANGE SCAN | INDEX_TAB02 | 1 | | 0 (0)|
--------------------------------------------------------------------------------
上述sql語句中cbo下oracle採取了nested loops迴圈巢狀,用tab01作為內部表,tab02作為外部表,注意執行計劃中選擇的是下面的表作為內部表,上面的為外部表,也就是驅動表。
由於外部表資料量比較小或者內部表上存在高效索引時,迴圈巢狀是比較高效的,迴圈巢狀連線能最快速地從結果集中提取第一批資料.其實rownum使用時,會產生一個count stopkey的計劃行,解釋為掃描表到前n行停止,當然這也可以當成很快的取出前一批資料的case。不過和nl意義卻大不相同!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25362835/viewspace-1057886/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 微課sql最佳化(14)、表的連線方法(3)-關於Nested Loops Join(巢狀迴圈)SQLOOP巢狀
- 【TUNE_ORACLE】列出返回行數較多的巢狀迴圈(NESTED LOOPS)SQL的SQL參考Oracle巢狀OOPSQL
- 迴圈_巢狀巢狀
- MySQL Join原理分析(緩衝塊巢狀與索引巢狀迴圈)MySql巢狀索引
- Python 迴圈巢狀Python巢狀
- 巢狀迴圈成本消耗巢狀
- nested loops 和hash join的一點測試OOP
- python怎麼迴圈巢狀Python巢狀
- python 跳出巢狀迴圈方法Python巢狀
- 兩表連線一:巢狀迴圈連線巢狀
- while + else 使用,while死迴圈與while的巢狀,for迴圈基本使用,range關鍵字,for的迴圈補充(break、continue、else) ,for迴圈的巢狀,基本資料型別及內建方法While巢狀資料型別
- Sql 巢狀迴圈最佳化案例SQL巢狀
- Python的if else 巢狀 和forin while 迴圈Python巢狀While
- python基礎語法迴圈巢狀和列表(一)Python巢狀
- 關於spring迴圈依賴的一點小感悟Spring
- NESTED LOOPS 成本計算OOP
- thinkphp中volist的多重迴圈,標籤巢狀PHP巢狀
- 最佳化兩個簡單的巢狀迴圈巢狀
- python 利用 for ... else 跳出雙層巢狀迴圈Python巢狀
- Linux Shell程式設計(17)——巢狀迴圈Linux程式設計巢狀
- Java | 靜態巢狀類(Static Nested Class)Java巢狀
- 迴圈中巢狀非同步操作的流程控制巢狀非同步
- Oracle的表連線方法(二)巢狀迴圈連線Oracle巢狀
- 關於 MySQL 的巢狀事務MySql巢狀
- java中如何將巢狀迴圈效能提高500倍Java巢狀
- 瞭解巢狀迴圈聯接、合併聯接巢狀
- 使用C++和Qt框架編寫的示例程式碼,用於解釋上述關於進入新事件迴圈、巢狀事件迴圈與延遲刪除相關的內容C++QT框架事件巢狀
- 巢狀類遞迴巢狀遞迴
- 關於一個迴圈請求與迴圈計時器的問題
- python基礎語法迴圈巢狀和列表(二)Python巢狀
- 記錄一次 postgresql 最佳化案例( 巢狀迴圈改HASH JOIN )SQL巢狀
- 關於MySQL遊標的巢狀使用MySql巢狀
- 高效遍歷匹配Json資料,避免巢狀迴圈[轉]JSON巢狀
- 1kb的前端HTML模板解析引擎,不限於巢狀、迴圈、函式你能想到的解析方式前端HTML巢狀函式
- 與小卡特一起學python 第11章 巢狀與可變迴圈Python巢狀
- 【sql調優之執行計劃】nested loops join and nested loop join outerSQLOOP
- [譯] D3.js 巢狀選擇集 (Nested Selection)JS巢狀
- oracle10g nested materialized view巢狀物化檢視示例OracleZedView巢狀