[20160213]閉包傳遞5.txt
[20160213]閉包傳遞5.txt
--所謂閉包傳遞是指sql語句的謂詞條件A=B and B=C 可以推出 A=C. oracle 的 最佳化器能夠利用這個特性最佳化sql語句。
--前一陣子看電子電子書<Apress.Expert.Oracle.SQL.Optimization.Deployment.and.Statistics.1430259779.pdf>測試連結:
http://blog.itpub.net/267265/viewspace-1981803/
http://blog.itpub.net/267265/viewspace-1987668/
http://blog.itpub.net/267265/viewspace-1988061/
1.環境:
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
-------------------- ----------- ---------------------------------------------------------------------------- ------
IBMPC/WIN_NT64-9.1.0 12.1.0.1.0 Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
create table t1 as select rownum id,rownum||'t1' name from dual connect by level<=5;
create table t2 as select rownum+1 id,rownum||'t2' name from dual connect by level<=5;
create table t3 as select rownum+2 id,rownum||'t3' name from dual connect by level<=5;
create table t4 as select rownum+3 id,rownum||'t3' name from dual connect by level<=5;
-- 分析表.Method_Opt => 'FOR ALL COLUMNS SIZE 1 '
-- 正常的連線還包含其它欄位的查詢,測試看看. t1.id=t2.id and t2.id=t3.id and t3.id=t4.id;
2.補充索引:
create unique index i_t1_id on t1(id);
create unique index i_t2_id on t2(id);
create unique index i_t3_id on t3(id);
create unique index i_t4_id on t4(id);
create index i_t1_name on t1(name);
3.繼續測試:
select * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1';
Plan hash value: 848093300
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 21 | 4 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 14 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | 7 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 7 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | I_T2_ID | 1 | | 0 (0)| |
|* 8 | INDEX UNIQUE SCAN | I_T3_ID | 1 | | 0 (0)| |
| 9 | TABLE ACCESS BY INDEX ROWID | T3 | 1 | 7 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T1@SEL$1
6 - SEL$1 / T2@SEL$1
7 - SEL$1 / T2@SEL$1
8 - SEL$1 / T3@SEL$1
9 - SEL$1 / T3@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."NAME"='4t1')
7 - access("T1"."ID"="T2"."ID")
8 - access("T3"."ID"="T2"."ID")
Note
-----
- this is an adaptive plan
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--可以看到連線順序 t1,t2,t3.
--如果人為實現t1,t3,t2看看.
select /*+leading(t1 t3 t2) */ * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1';
Plan hash value: 2643695722
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 8 (100)| | | | |
|* 1 | HASH JOIN | | 1 | 21 | 8 (0)| 00:00:01 | 1451K| 1451K| 932K (0)|
| 2 | MERGE JOIN CARTESIAN | | 5 | 70 | 5 (0)| 00:00:01 | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 7 | 2 (0)| 00:00:01 | | | |
|* 4 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 | | | |
| 5 | BUFFER SORT | | 5 | 35 | 3 (0)| 00:00:01 | 2048 | 2048 | 2048 (0)|
| 6 | TABLE ACCESS FULL | T3 | 5 | 35 | 3 (0)| 00:00:01 | | | |
| 7 | TABLE ACCESS FULL | T2 | 5 | 35 | 3 (0)| 00:00:01 | | | |
-----------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
6 - SEL$1 / T3@SEL$1
7 - SEL$1 / T2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."ID"="T2"."ID" AND "T2"."ID"="T3"."ID")
4 - access("T1"."NAME"='4t1')
Note
-----
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--可以看出沒有顯示的寫出條件 t1.id = t3.id ,出現的是CARTESIAN,而且t3,t2沒有選擇id索引.繼續人為指定看看:
select /*+leading(t1 t3 t2) index(t3 I_T3_ID) index(t2 I_T2_ID) */ * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1';
Plan hash value: 1569866173
--------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 6 (100)| | | | |
|* 1 | HASH JOIN | | 1 | 21 | 6 (0)| 00:00:01 | 1451K| 1451K| 932K (0)|
| 2 | MERGE JOIN CARTESIAN | | 5 | 70 | 4 (0)| 00:00:01 | | | |
| 3 | TABLE ACCESS BY INDEX ROWID | T1 | 1 | 7 | 2 (0)| 00:00:01 | | | |
|* 4 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 | | | |
| 5 | BUFFER SORT | | 5 | 35 | 2 (0)| 00:00:01 | 2048 | 2048 | 2048 (0)|
| 6 | TABLE ACCESS BY INDEX ROWID BATCHED| T3 | 5 | 35 | 2 (0)| 00:00:01 | | | |
| 7 | INDEX FULL SCAN | I_T3_ID | 5 | | 1 (0)| 00:00:01 | | | |
| 8 | TABLE ACCESS BY INDEX ROWID BATCHED | T2 | 5 | 35 | 2 (0)| 00:00:01 | | | |
| 9 | INDEX FULL SCAN | I_T2_ID | 5 | | 1 (0)| 00:00:01 | | | |
--------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
6 - SEL$1 / T3@SEL$1
7 - SEL$1 / T3@SEL$1
8 - SEL$1 / T2@SEL$1
9 - SEL$1 / T2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."ID"="T2"."ID" AND "T2"."ID"="T3"."ID")
4 - access("T1"."NAME"='4t1')
Note
-----
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--依舊出現MERGE JOIN CARTESIAN.
4.看來這個問題以前自己沒有注意:
--補上t1.id=t3.id條件.
select /*+leading(t1 t3 t2) index(t3 I_T3_ID) index(t2 I_T2_ID) */ * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1' and t1.id=t3.id;
Plan hash value: 1675215245
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 21 | 4 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 14 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | 7 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | T3 | 1 | 7 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | I_T3_ID | 1 | | 0 (0)| |
|* 8 | INDEX UNIQUE SCAN | I_T2_ID | 1 | | 0 (0)| |
| 9 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 7 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T1@SEL$1
6 - SEL$1 / T3@SEL$1
7 - SEL$1 / T3@SEL$1
8 - SEL$1 / T2@SEL$1
9 - SEL$1 / T2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."NAME"='4t1')
7 - access("T1"."ID"="T3"."ID")
8 - access("T2"."ID"="T3"."ID")
filter("T1"."ID"="T2"."ID")
Note
-----
- this is an adaptive plan
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--這樣就很好的使用索引.沒有出現笛卡爾集.
--所謂閉包傳遞是指sql語句的謂詞條件A=B and B=C 可以推出 A=C. oracle 的 最佳化器能夠利用這個特性最佳化sql語句。
--前一陣子看電子電子書<Apress.Expert.Oracle.SQL.Optimization.Deployment.and.Statistics.1430259779.pdf>測試連結:
http://blog.itpub.net/267265/viewspace-1981803/
http://blog.itpub.net/267265/viewspace-1987668/
http://blog.itpub.net/267265/viewspace-1988061/
1.環境:
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
-------------------- ----------- ---------------------------------------------------------------------------- ------
IBMPC/WIN_NT64-9.1.0 12.1.0.1.0 Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
create table t1 as select rownum id,rownum||'t1' name from dual connect by level<=5;
create table t2 as select rownum+1 id,rownum||'t2' name from dual connect by level<=5;
create table t3 as select rownum+2 id,rownum||'t3' name from dual connect by level<=5;
create table t4 as select rownum+3 id,rownum||'t3' name from dual connect by level<=5;
-- 分析表.Method_Opt => 'FOR ALL COLUMNS SIZE 1 '
-- 正常的連線還包含其它欄位的查詢,測試看看. t1.id=t2.id and t2.id=t3.id and t3.id=t4.id;
2.補充索引:
create unique index i_t1_id on t1(id);
create unique index i_t2_id on t2(id);
create unique index i_t3_id on t3(id);
create unique index i_t4_id on t4(id);
create index i_t1_name on t1(name);
3.繼續測試:
select * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1';
Plan hash value: 848093300
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 21 | 4 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 14 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | 7 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 7 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | I_T2_ID | 1 | | 0 (0)| |
|* 8 | INDEX UNIQUE SCAN | I_T3_ID | 1 | | 0 (0)| |
| 9 | TABLE ACCESS BY INDEX ROWID | T3 | 1 | 7 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T1@SEL$1
6 - SEL$1 / T2@SEL$1
7 - SEL$1 / T2@SEL$1
8 - SEL$1 / T3@SEL$1
9 - SEL$1 / T3@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."NAME"='4t1')
7 - access("T1"."ID"="T2"."ID")
8 - access("T3"."ID"="T2"."ID")
Note
-----
- this is an adaptive plan
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--可以看到連線順序 t1,t2,t3.
--如果人為實現t1,t3,t2看看.
select /*+leading(t1 t3 t2) */ * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1';
Plan hash value: 2643695722
-----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 8 (100)| | | | |
|* 1 | HASH JOIN | | 1 | 21 | 8 (0)| 00:00:01 | 1451K| 1451K| 932K (0)|
| 2 | MERGE JOIN CARTESIAN | | 5 | 70 | 5 (0)| 00:00:01 | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 7 | 2 (0)| 00:00:01 | | | |
|* 4 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 | | | |
| 5 | BUFFER SORT | | 5 | 35 | 3 (0)| 00:00:01 | 2048 | 2048 | 2048 (0)|
| 6 | TABLE ACCESS FULL | T3 | 5 | 35 | 3 (0)| 00:00:01 | | | |
| 7 | TABLE ACCESS FULL | T2 | 5 | 35 | 3 (0)| 00:00:01 | | | |
-----------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
6 - SEL$1 / T3@SEL$1
7 - SEL$1 / T2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."ID"="T2"."ID" AND "T2"."ID"="T3"."ID")
4 - access("T1"."NAME"='4t1')
Note
-----
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--可以看出沒有顯示的寫出條件 t1.id = t3.id ,出現的是CARTESIAN,而且t3,t2沒有選擇id索引.繼續人為指定看看:
select /*+leading(t1 t3 t2) index(t3 I_T3_ID) index(t2 I_T2_ID) */ * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1';
Plan hash value: 1569866173
--------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 6 (100)| | | | |
|* 1 | HASH JOIN | | 1 | 21 | 6 (0)| 00:00:01 | 1451K| 1451K| 932K (0)|
| 2 | MERGE JOIN CARTESIAN | | 5 | 70 | 4 (0)| 00:00:01 | | | |
| 3 | TABLE ACCESS BY INDEX ROWID | T1 | 1 | 7 | 2 (0)| 00:00:01 | | | |
|* 4 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 | | | |
| 5 | BUFFER SORT | | 5 | 35 | 2 (0)| 00:00:01 | 2048 | 2048 | 2048 (0)|
| 6 | TABLE ACCESS BY INDEX ROWID BATCHED| T3 | 5 | 35 | 2 (0)| 00:00:01 | | | |
| 7 | INDEX FULL SCAN | I_T3_ID | 5 | | 1 (0)| 00:00:01 | | | |
| 8 | TABLE ACCESS BY INDEX ROWID BATCHED | T2 | 5 | 35 | 2 (0)| 00:00:01 | | | |
| 9 | INDEX FULL SCAN | I_T2_ID | 5 | | 1 (0)| 00:00:01 | | | |
--------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
3 - SEL$1 / T1@SEL$1
4 - SEL$1 / T1@SEL$1
6 - SEL$1 / T3@SEL$1
7 - SEL$1 / T3@SEL$1
8 - SEL$1 / T2@SEL$1
9 - SEL$1 / T2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."ID"="T2"."ID" AND "T2"."ID"="T3"."ID")
4 - access("T1"."NAME"='4t1')
Note
-----
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--依舊出現MERGE JOIN CARTESIAN.
4.看來這個問題以前自己沒有注意:
--補上t1.id=t3.id條件.
select /*+leading(t1 t3 t2) index(t3 I_T3_ID) index(t2 I_T2_ID) */ * from t1,t2,t3 where t1.id=t2.id and t2.id=t3.id and t1.name='4t1' and t1.id=t3.id;
Plan hash value: 1675215245
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 21 | 4 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 14 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | 7 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_T1_NAME | 1 | | 1 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | T3 | 1 | 7 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | I_T3_ID | 1 | | 0 (0)| |
|* 8 | INDEX UNIQUE SCAN | I_T2_ID | 1 | | 0 (0)| |
| 9 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 7 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
4 - SEL$1 / T1@SEL$1
5 - SEL$1 / T1@SEL$1
6 - SEL$1 / T3@SEL$1
7 - SEL$1 / T3@SEL$1
8 - SEL$1 / T2@SEL$1
9 - SEL$1 / T2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."NAME"='4t1')
7 - access("T1"."ID"="T3"."ID")
8 - access("T2"."ID"="T3"."ID")
filter("T1"."ID"="T2"."ID")
Note
-----
- this is an adaptive plan
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
--這樣就很好的使用索引.沒有出現笛卡爾集.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-1988312/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用閉包傳遞引數
- POJ 3360-Cow Contest(傳遞閉包)
- [20160212]閉包傳遞4.txt
- [20160211]閉包傳遞3.txt
- [20160210]閉包傳遞2.txt
- POJ3660 Cow Contest【Floyd演算法 傳遞閉包】演算法
- [20160125]閉包傳遞問題.txt
- swift 閉包傳值Swift
- poj2594Treasure Exploration【最小路徑覆蓋+floyd傳遞閉包】
- JS函式表示式——函式遞迴、閉包JS函式遞迴
- 值傳遞與引用傳遞
- 值傳遞和引用傳遞
- 閉包
- BZOJ 1612 [Usaco2008 Jan]Cow Contest奶牛的比賽:floyd傳遞閉包
- 用閉包替換遞迴實現斐波拉契數列遞迴
- 閉包 | 淺談JavaScript閉包問題JavaScript
- Swift-逃逸閉包、自動閉包Swift
- Windows 10傳遞最佳化功能有什麼用 Windows 10傳遞最佳化功能怎麼關閉Windows
- JavaScript的值傳遞和引用傳遞JavaScript
- 快速搞懂值傳遞與引用傳遞
- Java的值傳遞和引用傳遞Java
- Python3之從遞迴到閉包再到裝飾器Python遞迴
- 【集合論】關係閉包 ( 關係閉包求法 | 關係圖求閉包 | 關係矩陣求閉包 | 閉包運算與關係性質 | 閉包複合運算 )矩陣
- PHP 閉包PHP
- JavaScript閉包JavaScript
- Golang閉包Golang
- golang 閉包Golang
- JavaScript 閉包JavaScript
- 理解“閉包”
- Swift 閉包Swift
- Swift,閉包Swift
- 理解閉包
- Swift - 閉包Swift
- lisp 閉包Lisp
- JavaScript - 閉包JavaScript
- go 值傳遞和地址傳遞的例子Go
- Java - 是值傳遞還是引用傳遞Java
- Java中的值傳遞和引用傳遞Java