[20170203]12c left right 外連線的增強
[20170203]12c left right 外連線的增強.txt
--相關連結:http://blog.itpub.net/267265/viewspace-1593068/
--連結提到我個人更加喜歡使用(+)的風格,如果使用10053跟蹤,oracle sql內部引擎實際轉化為(+)語法.
--測試一下12c在這方面的增強:
1.環境:
SCOTT@book> @ &r/ver1
PORT_STRING VERSION BANNER
-------------------- -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
create table t1 as select rownum id,rownum||'t1' data from dual connect by level<=5;
create table t2 as select rownum+1 id,rownum||'t2' data from dual connect by level<=5;
create table t3 as select rownum+2 id,rownum||'t3' data from dual connect by level<=5;
--分析略.Method_Opt => 'FOR ALL COLUMNS SIZE 1 '
2.測試:
--如果在11g下寫成如下是無法執行的.
SCOTT@book> SELECT t1.*,t2.*,t3.* FROM t1 , t2 , t3 WHERE t1.id = t2.id(+) AND t3.id = t2.id(+) ORDER BY 1;
SELECT t1.*,t2.*,t3.* FROM t1 , t2 , t3 WHERE t1.id = t2.id(+) AND t3.id = t2.id(+) ORDER BY 1
*
ERROR at line 1:
ORA-01417: a table may be outer joined to at most one other table
$ oerr ora 01417
01417, 00000, "a table may be outer joined to at most one other table"
// *Cause: a.b (+) = b.b and a.c (+) = c.c is not allowed
// *Action: Check that this is really what you want, then join b and c first
// in a view.
--在11g要改寫如下:
with tt as (SELECT t1.id t1_id,t1.data t1_data,t2.id t2_id,t2.data t2_data FROM t1 , t2 WHERE t1.id = t2.id(+) )
select tt.*,t3.* from tt,t3 where t3.id = tt.t2_id(+) ORDER BY 1;
T1_ID T1_DATA T2_ID T2_DATA ID DATA
----- ------- ----- ------- --- -----
3 3t1 3 2t2 3 1t3
4 4t1 4 3t2 4 2t3
5 5t1 5 4t2 5 3t3
6 4t3
7 5t3
--//不對,看下面的連結...
3.12c呢?
SCOTT@ztest> @ 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' data from dual connect by level<=5;
create table t2 as select rownum+1 id,rownum||'t2' data from dual connect by level<=5;
create table t3 as select rownum+2 id,rownum||'t3' data from dual connect by level<=5;
--分析略.Method_Opt => 'FOR ALL COLUMNS SIZE 1 '
SCOTT@ztest> set null null
SCOTT@ztest> SELECT t1.*,t2.*,t3.* FROM t1 , t2 , t3 WHERE t1.id = t2.id(+) AND t3.id = t2.id(+) ORDER BY 1;
ID DATA ID DATA ID DATA
--- ----- ---------- ----- -- ------
1 1t1 null null 5 3t3
1 1t1 null null 7 5t3
1 1t1 null null 6 4t3
1 1t1 null null 4 2t3
1 1t1 null null 3 1t3
2 2t1 null null 5 3t3
2 2t1 null null 6 4t3
2 2t1 null null 3 1t3
2 2t1 null null 7 5t3
2 2t1 null null 4 2t3
3 3t1 null null 6 4t3
3 3t1 null null 4 2t3
3 3t1 null null 5 3t3
3 3t1 3 2t2 3 1t3
3 3t1 null null 7 5t3
4 4t1 4 3t2 4 2t3
4 4t1 null null 6 4t3
4 4t1 null null 7 5t3
4 4t1 null null 3 1t3
4 4t1 null null 5 3t3
5 5t1 null null 3 1t3
5 5t1 null null 7 5t3
5 5t1 5 4t2 5 3t3
5 5t1 null null 4 2t3
5 5t1 null null 6 4t3
25 rows selected.
--//不過結果相差甚遠....^_^.看看執行計劃:
SCOTT@ztest> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID brzjuhsm3u3uq, child number 0
-------------------------------------
SELECT t1.*,t2.*,t3.* FROM t1 , t2 , t3 WHERE t1.id = t2.id(+) AND
t3.id = t2.id(+) ORDER BY 1
Plan hash value: 3763024351
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 13 (100)| | | | |
| 1 | SORT ORDER BY | | 25 | 525 | 13 (0)| 00:00:01 | 2048 | 2048 | 2048 (0)|
|* 2 | HASH JOIN OUTER | | 25 | 525 | 13 (0)| 00:00:01 | 1451K| 1451K| 1331K (0)|
| 3 | MERGE JOIN CARTESIAN| | 25 | 350 | 10 (0)| 00:00:01 | | | |
| 4 | TABLE ACCESS FULL | T1 | 5 | 35 | 3 (0)| 00:00:01 | | | |
| 5 | BUFFER SORT | | 5 | 35 | 7 (0)| 00:00:01 | 2048 | 2048 | 2048 (0)|
| 6 | TABLE ACCESS FULL | T3 | 5 | 35 | 1 (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
4 - SEL$1 / T1@SEL$1
6 - SEL$1 / T3@SEL$1
7 - SEL$1 / T2@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T1"."ID"="T2"."ID" AND "T3"."ID"="T2"."ID")
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
39 rows selected.
--看來我理解連線錯誤嗎?11G寫成如下:
WITH tx
AS (SELECT t1.id t1_id
,t1.data t1_data
,t3.id t3_id
,t3.data t3_data
FROM t1, t3)
SELECT tx.t1_id
,tx.t1_data
,T2.ID
,t2.data
,tx.t3_id
,tx.t3_data
FROM tx, t2
WHERE tx.t1_id = t2.id(+) AND tx.t3_id = t2.id(+)
ORDER BY 1;
--執行如下2者輸出都是no rows selected.
WITH tx
AS (SELECT t1.id t1_id
,t1.data t1_data
,t3.id t3_id
,t3.data t3_data
FROM t1, t3)
SELECT tx.t1_id
,tx.t1_data
,T2.ID
,t2.data
,tx.t3_id
,tx.t3_data
FROM tx, t2
WHERE tx.t1_id = t2.id(+) AND tx.t3_id = t2.id(+)
minus
SELECT t1.*,t2.*,t3.* FROM t1 , t2 , t3 WHERE t1.id = t2.id(+) AND t3.id = t2.id(+) ;
WITH tx
AS (SELECT t1.id t1_id
,t1.data t1_data
,t3.id t3_id
,t3.data t3_data
FROM t1, t3)
SELECT t1.*,t2.*,t3.* FROM t1 , t2 , t3 WHERE t1.id = t2.id(+) AND t3.id = t2.id(+)
minus
SELECT tx.t1_id
,tx.t1_data
,T2.ID
,t2.data
,tx.t3_id
,tx.t3_data
FROM tx, t2
WHERE tx.t1_id = t2.id(+) AND tx.t3_id = t2.id(+);
--//我再思考的問題是如果12c以後會不會有人寫成:
SELECT t1.*,t2.*,t3.* FROM t1 , t2 , t3 WHERE t1.id = t2.id(+) AND t3.id = t2.id(+) ORDER BY 1;
--//而實際不需要這樣的結果集.只能在以後最佳化sql語句時注意這個問題.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2133030/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 用實驗方法加深理解Oracle的外連線(left/right/full)和內連線(inner)Oracle
- 兩種連線的表達 :left(right) join 和 (+)
- mysql常用連線查詢join,left,right,crossMySqlROS
- mysql INNER JOIN、LEFT JOIN、RIGHT JOIN;內連線(等值連線)、左連線、右連線MySql
- 連線查詢簡析 join 、 left join 、 right join
- clear:left/right 理解
- Oracle Left join right jionOracle
- sql中的join、left join、right joinSQL
- MySQL LEFT JOIN/ INNER JOIN/RIGHT JOINMySql
- Sql 中的 left 函式、right 函式SQL函式
- LEFT JOIN 和JOIN 多表連線
- 【SQL】Oracle的內連線、左外連線、右外連線及全外連線SQLOracle
- sql left join 和 right join解釋SQL
- SQL的四種連線:內連線 左外連線 右外連線 全連線SQL
- sql之left join、right join、inner join的區別SQL
- Oracle內連線、外連線、右外連線、全外連線小總結Oracle
- ORACLE 12C RMAN 功能增強Oracle
- 深入理解SQL的四種連線-左外連線、右外連線、內連線、全連線SQL
- Oracle左外連線、右外連線、完全外連線以及(+)號用法Oracle
- Oracle 左外連線、右外連線、全外連線小總結Oracle
- 內連線、外連線
- join、inner join、left join、right join、outer join的區別
- Oracle 12c中的轉換功能增強Oracle
- Oracle 12c中增強的PL/SQL功能OracleSQL
- sql的left join 、right join 、inner join之間的區別SQL
- mysql中的left join、right join 、inner join的詳細用法MySql
- sql 連線查詢例項(left join)三表連線查詢SQL
- sybase的外連線
- Spring Boot中增強對MongoDB的配置(連線池等)Spring BootMongoDB
- Oracle11gr2簡易連線增強(二)Oracle
- Oracle11gr2簡易連線增強(一)Oracle
- left和right屬性也可以設定元素的寬度
- left join,right join,inner join的條件on和where的區別
- sql 內連線和外連線SQL
- 外連線與連線順序
- 內連線、外連線總結
- SQL SERVER 自連線、外連線SQLServer
- PostgreSQL 14中連線引數target_session_attrs增強SQLSession