[20160219]关于连接顺序.txt

[20160219]关于连接顺序.txt

--今天被问一个问题,如果使用外连接的情况,连接顺序可以改变吗?我只能说我给测试看看,再回答这个问题:

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

2.测试:
select * from dept,emp where dept.deptno=emp.deptno(+);

Plan hash value: 2251696546
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |        |       |     6 (100)|          |       |       |          |
|   1 |  MERGE JOIN OUTER            |         |     14 |   812 |     6  (17)| 00:00:01 |       |       |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |      4 |    80 |     2   (0)| 00:00:01 |       |       |          |
|   3 |    INDEX FULL SCAN           | PK_DEPT |      4 |       |     1   (0)| 00:00:01 |       |       |          |
|*  4 |   SORT JOIN                  |         |     14 |   532 |     4  (25)| 00:00:01 |  2048 |  2048 | 2048  (0)|
|   5 |    TABLE ACCESS FULL         | EMP     |     14 |   532 |     3   (0)| 00:00:01 |       |       |          |
--------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$1 / DEPT@SEL$1
   3 - SEL$1 / DEPT@SEL$1
   5 - SEL$1 / EMP@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
       filter("DEPT"."DEPTNO"="EMP"."DEPTNO")

--看是否可以提示改变连接顺序。

3.继续测试:
select /*+ leading(emp dept) use_hash(dept) */ * from dept,emp where dept.deptno=emp.deptno(+);

Plan hash value: 2251696546
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |        |       |     6 (100)|          |       |       |          |
|   1 |  MERGE JOIN OUTER            |         |     14 |   812 |     6  (17)| 00:00:01 |       |       |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |      4 |    80 |     2   (0)| 00:00:01 |       |       |          |
|   3 |    INDEX FULL SCAN           | PK_DEPT |      4 |       |     1   (0)| 00:00:01 |       |       |          |
|*  4 |   SORT JOIN                  |         |     14 |   532 |     4  (25)| 00:00:01 |  2048 |  2048 | 2048  (0)|
|   5 |    TABLE ACCESS FULL         | EMP     |     14 |   532 |     3   (0)| 00:00:01 |       |       |          |
--------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$1 / DEPT@SEL$1
   3 - SEL$1 / DEPT@SEL$1
   5 - SEL$1 / EMP@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
       filter("DEPT"."DEPTNO"="EMP"."DEPTNO")

--可以发现提示无效。视乎存在外连接左右连接的情况无法改变连接顺序,这个在优化sql语句中注意。

4.继续测试,建立emp.ename索引,并且唯一。

SCOTT@book> select  * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename='KING';
    DEPTNO DNAME          LOC                EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- -------------- ------------- ---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
        10 ACCOUNTING     NEW YORK            7839 KING       PRESIDENT            1981-11-17 00:00:00       5000                    10

Plan hash value: 3311718186
---------------------------------------------------------------------------------------------
| Id  | Operation                    | Name        | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |        |       |     3 (100)|          |
|   1 |  NESTED LOOPS                |             |      1 |    58 |     3   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMP         |      1 |    38 |     2   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | I_EMP_ENAME |      1 |       |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| DEPT        |      1 |    20 |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN         | PK_DEPT     |      1 |       |     0   (0)|          |
---------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$C30CFC9A
   2 - SEL$C30CFC9A / EMP@SEL$1
   3 - SEL$C30CFC9A / EMP@SEL$1
   4 - SEL$C30CFC9A / DEPT@SEL$1
   5 - SEL$C30CFC9A / DEPT@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("EMP"."ENAME"='KING')
   5 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")

--这个时候视乎改变了连接顺序,而且不存在外连接执行计划。但是实际上这里的+实际上多余的。如果要实现外连接应该写成:

select  * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)='KING';

SCOTT@book> select  * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)='KING';
    DEPTNO DNAME          LOC                EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- -------------- ------------- ---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
        10 ACCOUNTING     NEW YORK            7839 KING       PRESIDENT            1981-11-17 00:00:00       5000                    10
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

Plan hash value: 965809594
-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name        | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |             |        |       |     5 (100)|          |       |       |          |
|   1 |  MERGE JOIN OUTER             |             |      4 |   232 |     5  (20)| 00:00:01 |       |       |          |
|   2 |   TABLE ACCESS BY INDEX ROWID | DEPT        |      4 |    80 |     2   (0)| 00:00:01 |       |       |          |
|   3 |    INDEX FULL SCAN            | PK_DEPT     |      4 |       |     1   (0)| 00:00:01 |       |       |          |
|*  4 |   SORT JOIN                   |             |      1 |    38 |     3  (34)| 00:00:01 |  2048 |  2048 | 2048  (0)|
|   5 |    TABLE ACCESS BY INDEX ROWID| EMP         |      1 |    38 |     2   (0)| 00:00:01 |       |       |          |
|*  6 |     INDEX UNIQUE SCAN         | I_EMP_ENAME |      1 |       |     1   (0)| 00:00:01 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$1 / DEPT@SEL$1
   3 - SEL$1 / DEPT@SEL$1
   5 - SEL$1 / EMP@SEL$1
   6 - SEL$1 / EMP@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
       filter("DEPT"."DEPTNO"="EMP"."DEPTNO")
   6 - access("EMP"."ENAME"='KING')

--如果使用提示:

select /*+ leading(emp dept) */ * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)='KING';

Plan hash value: 965809594
-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name        | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |             |        |       |     5 (100)|          |       |       |          |
|   1 |  MERGE JOIN OUTER             |             |      4 |   232 |     5  (20)| 00:00:01 |       |       |          |
|   2 |   TABLE ACCESS BY INDEX ROWID | DEPT        |      4 |    80 |     2   (0)| 00:00:01 |       |       |          |
|   3 |    INDEX FULL SCAN            | PK_DEPT     |      4 |       |     1   (0)| 00:00:01 |       |       |          |
|*  4 |   SORT JOIN                   |             |      1 |    38 |     3  (34)| 00:00:01 |  2048 |  2048 | 2048  (0)|
|   5 |    TABLE ACCESS BY INDEX ROWID| EMP         |      1 |    38 |     2   (0)| 00:00:01 |       |       |          |
|*  6 |     INDEX UNIQUE SCAN         | I_EMP_ENAME |      1 |       |     1   (0)| 00:00:01 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$1 / DEPT@SEL$1
   3 - SEL$1 / DEPT@SEL$1
   5 - SEL$1 / EMP@SEL$1
   6 - SEL$1 / EMP@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
       filter("DEPT"."DEPTNO"="EMP"."DEPTNO")
   6 - access("EMP"."ENAME"='KING')

--可以发现连接顺序并没有改变。
--可以看出存在外连接的情况下,无法改变连接顺序的。

时间: 2024-09-20 10:39:31

[20160219]关于连接顺序.txt的相关文章

[20160330]关于连接顺序3.txt

[20160330]关于连接顺序3.txt --关于连接顺序,曾经写过两篇blog,链接如下: http://blog.itpub.net/267265/viewspace-1991306/ http://blog.itpub.net/267265/viewspace-1991787/ --今天才发现自己犯了一个严重错误,使用外连接的情况,连接顺序是可以改变的,以前的blog存在严重错误-(:) --还是通过例子来讲解: 1.环境: SCOTT@book> @ &r/ver1 PORT_ST

[20160220]关于连接顺序2.txt

[20160220]关于连接顺序2.txt --前几天被问一个问题,如果使用外连接的情况,连接顺序可以改变吗?我只能说我给测试看看,再回答这个问题: --链接测试已经说明存在外连接的情况下,无法改变连接顺序的. --今天想想忘记考虑全连接的情况,继续测试: 1.环境: SCOTT@test01p> @ ver1 PORT_STRING                    VERSION        BANNER                                         

[20140823]12c join convert连接转换.txt

[20140823]12c join convert连接转换.txt --前面提高12c执行计划的Partial Join Evaluation.现在看看12c join convert. --链接: 1.建立测试环境: SCOTT@test01p> @ver BANNER                                                                               CON_ID ---------------------------

SQL优化之针对count、表的连接顺序、条件顺序、in及exist的优化_oracle

本文详述了SQL优化中针对count.表的连接顺序.条件顺序.in及exist的优化,非常具有实用价值!详述如下: 一.关于count 看过一些网上关于count(*)和count(列)的文章,count(列)的效率一定比count(*)高吗? 其实个人觉得count(*)和count(列)根本就没有可比性,count(*)统计的是表里面的总条数,而count(列)统计的是当列的非空记录条数. 不过我们可以通过实验来比较一下: 首先创建测试表: drop table test purge; cr

[20170825]11G备库启用DRCP连接3.txt

[20170825]11G备库启用DRCP连接3.txt --//昨天测试了11G备库启用DRCP连接,要设置alter system set audit_trail=none scope=spfile ; --//参考链接http://blog.itpub.net/267265/viewspace-2144036/. --//在测试过程中我遇到1个奇怪问题,就是如果主库没有打开drcp,备库执行exec dbms_connection_pool.start_pool();失败. --//今天分

[20111223]索引键值在B tree索引块中的顺序.txt

[20111223]索引键值在B tree索引块中的顺序.txt 参考链接:http://www.adellera.it/blog/2009/05/24/order-keys-inside-index-blocks/ 自己为了加强理解重复一下对方的测试! 1.建立测试表以及索引 SQL> select * from v$version; BANNER -------------------------------------------------------------------------

Oracle性能优化学习笔记之WHERE子句中的连接顺序

        ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.         例如:        (低效,执行时间156.3秒) SELECT - FROM EMP E WHERE SAL > 50000 AND JOB = 'MANAGER' AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);      

[20120120]startup nomount访问参数文件的顺序.txt

检查startup nomount访问参数文件的顺序. export ORACLE_SID=noexiststrace -o noexist.txt sqlplus sys as sysdba $ rlsqlplus SQL*Plus: Release 11.2.0.1.0 Production on Fri Jan 20 08:48:12 2012 Copyright (c) 1982, 2009, Oracle.  All rights reserved. Enter password:Co

[20160212]闭包传递4.txt

[20160212]闭包传递4.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.