Hint&ordered&leading&use_nl

Oracle官方文档:Oracle Database SQL Language Reference

1、ordered hint

2、leading hint

3、use_nl

1、ordered hint

/*+ ORDERED */

The ORDERED hint instructs Oracleto join tables in the order in which they appear in the FROM clause.Oracle recommends that you use the LEADING hint, which is more versatile than the ORDERED hint.

When you omit the ORDERED hint from a SQL statement requiring a join, the optimizer chooses the order in which to join the tables. You might want to use the ORDERED hint to specify a join order if you know something that the optimizer does not know about the number of rows selected from each table. Such information lets you choose an inner and outer table better than the optimizer could.

2、leading hint

/*+ LEADING ( [ @ queryblock ] tablespec [ tablespec ]... ) */

The LEADING hint instructs the optimizerto use the specified set of tables as the prefix in the execution plan. This hint is more versatile than the ORDERED hint.

The LEADING hint is ignored if the tables specified cannot be joined first in the order specified because of dependencies in the join graph. If you specify two or more conflicting LEADING hints, then all of them are ignored. If you specify the ORDERED hint, it overrides all LEADING hints.

3、use_nl hint

The USE_NL hint instructs the optimizer to join each specified table to another row source with a nested loops join, using the pecified table as the inner table.

Use of the USE_NL and USE_MERGE hints is recommended with the LEADING and ORDERED hints. The optimizer uses those hints when the referenced table is forced tobe the inner table of a join. The hints are ignored if the referenced table is the outer table.

 

--USE_NL强制把referenced table作为inner table。如果referenced table 为outer table,则此hint被忽略(即不管用)--个人觉得这句话是废话。

--实例1:
--/*+ ordered */ hint实例,表BASOPT上有optid列上的索引PK_BASOPT
SQL> set autot trace exp
--不用/*+ ordered */hint,BASOPTUSER作为驱动表,用BASOPTUSER去连接BASOPT表
SQL> select optname,userid from basopt a,basoptuser b where a.optid = b.optid and b.userid = 1;

执行计划
----------------------------------------------------------
Plan hash value: 922486247

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |            |     1 |    19 |     4   (0)| 00:00:01 |

|   1 |  NESTED LOOPS                |            |       |       |            |          |

|   2 |   NESTED LOOPS               |            |     1 |    19 |     4   (0)| 00:00:01 |

|*  3 |    TABLE ACCESS FULL         | BASOPTUSER |     1 |     8 |     3   (0)| 00:00:01 |

|*  4 |    INDEX UNIQUE SCAN         | PK_BASOPT  |     1 |       |     0   (0)| 00:00:01 |

|   5 |   TABLE ACCESS BY INDEX ROWID| BASOPT     |     1 |    11 |     1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("B"."USERID"=1)
   4 - access("A"."OPTID"="B"."OPTID")
--用/*+ ordered */hint 来指定按照from后边表的顺序来连接表,用BASOPT去连接BASOPTUSER表,此时优化器选择了另一种链接方法:MERGE JOIN
SQL> select /*+ ordered */ optname,userid from basopt a,basoptuser b where a.optid = b.optid and b.userid = 1;

执行计划
----------------------------------------------------------
Plan hash value: 2164325570

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |            |     1 |    19 |     6  (17)| 00:00:01 |

|   1 |  MERGE JOIN                  |            |     1 |    19 |     6  (17)| 00:00:01 |

|   2 |   TABLE ACCESS BY INDEX ROWID| BASOPT     |     2 |    22 |     2   (0)| 00:00:01 |

|   3 |    INDEX FULL SCAN           | PK_BASOPT  |     2 |       |     1   (0)| 00:00:01 |

|*  4 |   SORT JOIN                  |            |     1 |     8 |     4  (25)| 00:00:01 |

|*  5 |    TABLE ACCESS FULL         | BASOPTUSER |     1 |     8 |     3   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("A"."OPTID"="B"."OPTID")
       filter("A"."OPTID"="B"."OPTID")
   5 - filter("B"."USERID"=1)
--用use_nl(b)指定使用nested loops连接使用basoptuser作为內表
SQL> select /*+ ordered use_nl(b)*/ optname,userid from basopt a,basoptuser b where a.optid = b.optid and b.userid = 1;

执行计划
----------------------------------------------------------
Plan hash value: 3306984809

--------------------------------------------------------------------------------

-

| Id  | Operation          | Name       | Rows  | Bytes | Cost (%CPU)| Time
|

--------------------------------------------------------------------------------

-

|   0 | SELECT STATEMENT   |            |     1 |    19 |     7   (0)| 00:00:01
|

|   1 |  NESTED LOOPS      |            |     1 |    19 |     7   (0)| 00:00:01
|

|   2 |   TABLE ACCESS FULL| BASOPT     |     2 |    22 |     3   (0)| 00:00:01
|

|*  3 |   TABLE ACCESS FULL| BASOPTUSER |     1 |     8 |     2   (0)| 00:00:01
|

--------------------------------------------------------------------------------

-


Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("B"."USERID"=1 AND "A"."OPTID"="B"."OPTID")

SQL>

 

--实例2:
--/*+ leading() */ hint实例,表BASOPT上有optid列上的索引PK_BASOPT,表SYSUSER上有userid列上的索引PK_SYSUSER
SQL> select optname,c.userid from basopt a,basoptuser b,sysuser c where a.optid = b.optid and b.userid = c.userid and b.userid = 1;

执行计划
----------------------------------------------------------
Plan hash value: 1787196989

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |            |     1 |    22 |     4   (0)| 00:00:01 |

|   1 |  NESTED LOOPS                |            |       |       |            |          |

|   2 |   NESTED LOOPS               |            |     1 |    22 |     4   (0)| 00:00:01 |

|   3 |    NESTED LOOPS              |            |     1 |    11 |     3   (0)| 00:00:01 |

|*  4 |     INDEX UNIQUE SCAN        | PK_SYSUSER |     1 |     3 |     0   (0)| 00:00:01 |

|*  5 |     TABLE ACCESS FULL        | BASOPTUSER |     1 |     8 |     3   (0)| 00:00:01 |

|*  6 |    INDEX UNIQUE SCAN         | PK_BASOPT  |     1 |       |     0   (0)| 00:00:01 |

|   7 |   TABLE ACCESS BY INDEX ROWID| BASOPT     |     1 |    11 |     1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("C"."USERID"=1)
   5 - filter("B"."USERID"=1)
   6 - access("A"."OPTID"="B"."OPTID")
--设定驱动表b c
SQL> select /*+ leading(b c) */  optname,c.userid from basopt a,basoptuser b,sysuser c where a.optid = b.optid and b.userid = c.userid and b.userid = 1;

执行计划
----------------------------------------------------------
Plan hash value: 3853709033

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |            |     1 |    22 |     4   (0)| 00:00:01 |

|   1 |  NESTED LOOPS                |            |       |       |            |          |

|   2 |   NESTED LOOPS               |            |     1 |    22 |     4   (0)| 00:00:01 |

|   3 |    MERGE JOIN CARTESIAN      |            |     1 |    11 |     3   (0)| 00:00:01 |

|*  4 |     TABLE ACCESS FULL        | BASOPTUSER |     1 |     8 |     3   (0)| 00:00:01 |

|   5 |     BUFFER SORT              |            |     1 |     3 |     0   (0)| 00:00:01 |

|*  6 |      INDEX UNIQUE SCAN       | PK_SYSUSER |     1 |     3 |     0   (0)| 00:00:01 |

|*  7 |    INDEX UNIQUE SCAN         | PK_BASOPT  |     1 |       |     0   (0)| 00:00:01 |

|   8 |   TABLE ACCESS BY INDEX ROWID| BASOPT     |     1 |    11 |     1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - filter("B"."USERID"=1)
   6 - access("C"."USERID"=1)
   7 - access("A"."OPTID"="B"."OPTID")
--设定驱动表b a
SQL> select /*+ leading(b a) */  optname,c.userid from basopt a,basoptuser b,sysuser c where a.optid = b.optid and b.userid = c.userid and b.userid = 1;

执行计划
----------------------------------------------------------
Plan hash value: 1915872201

--------------------------------------------------------------------------------------------

| Id  | Operation                     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT              |            |     1 |    22 |     4   (0)| 00:00:01 |

|   1 |  MERGE JOIN CARTESIAN         |            |     1 |    22 |     4   (0)| 00:00:01 |

|   2 |   NESTED LOOPS                |            |       |       |            |          |

|   3 |    NESTED LOOPS               |            |     1 |    19 |     4   (0)| 00:00:01 |

|*  4 |     TABLE ACCESS FULL         | BASOPTUSER |     1 |     8 |     3   (0)| 00:00:01 |

|*  5 |     INDEX UNIQUE SCAN         | PK_BASOPT  |     1 |       |     0   (0)| 00:00:01 |

|   6 |    TABLE ACCESS BY INDEX ROWID| BASOPT     |     1 |    11 |     1   (0)| 00:00:01 |

|   7 |   BUFFER SORT                 |            |     1 |     3 |     3   (0)| 00:00:01 |

|*  8 |    INDEX UNIQUE SCAN          | PK_SYSUSER |     1 |     3 |     0   (0)| 00:00:01 |

--------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - filter("B"."USERID"=1)
   5 - access("A"."OPTID"="B"."OPTID")
   8 - access("C"."USERID"=1)
--设定驱动表b c,并且b和c表之间的连接使用nested loops连接
SQL> select /*+ leading(b c) use_nl(b c) */  optname,c.userid from basopt a,basoptuser b,sysuser c where a.optid = b.optid and b.userid = c.userid and b.userid
= 1;

执行计划
----------------------------------------------------------
Plan hash value: 683070851

-------------------------------------------------------------------------------------------

| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |            |     1 |    22 |     4   (0)| 00:00:01 |

|   1 |  NESTED LOOPS                |            |       |       |            |          |

|   2 |   NESTED LOOPS               |            |     1 |    22 |     4   (0)| 00:00:01 |

|   3 |    NESTED LOOPS              |            |     1 |    11 |     3   (0)| 00:00:01 |

|*  4 |     TABLE ACCESS FULL        | BASOPTUSER |     1 |     8 |     3   (0)| 00:00:01 |

|*  5 |     INDEX UNIQUE SCAN        | PK_SYSUSER |     1 |     3 |     0   (0)| 00:00:01 |

|*  6 |    INDEX UNIQUE SCAN         | PK_BASOPT  |     1 |       |     0   (0)| 00:00:01 |

|   7 |   TABLE ACCESS BY INDEX ROWID| BASOPT     |     1 |    11 |     1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - filter("B"."USERID"=1)
   5 - access("C"."USERID"=1)
   6 - access("A"."OPTID"="B"."OPTID")

SQL>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值