zoukankan      html  css  js  c++  java
  • Oracle 优化 ordered 和leading 使用

    问题:请教HINT写法

    我有一个SQL添加如下hint,目的是指定hash_join方式。

    select /*+ordered use_hash(a,b,c,d) */ *
    From a,b,c,d
    Where ...

    其中,
          a只与b有关联关系,b只与c有关联关系,b只与c有关联关系,c只与d有关联关系,
        数量级:a:1000条,  b:100 万条, c:800万条 , d:100万条


    执行计划为:
    Hash Join 
       ---Hash Join 
           -----  Hash Join 
                   ------  a
                   -----    b
           -----  c
       ---d

    考虑到d表比较小,我能不能做到将d表作为驱动表、而a,b,c关联之后的结果作为prob外表呢,
    通过Ordered好像是没有办法控制这样,加了就只能是a作为驱动表装载内存,b作为prob表与之关联,
    之后的结果再作为驱动表,以此类推。

    用Leading可以吗?请给出语法,谢谢。
     
    解答:
     
    oracle 10g中

    hash_join可以通过no_swap_join_inputs/swap_join_inputs来强制控制build表,配合leading或者ordered可以控制多表之前的连接顺序。

    比如t1,t2,t3,t4共4张表做hash_join
    可以通过ordered+no_swap_join_inputs/swap_join_inputs来实现。
    比如
    如果想实现

    ( T3 hash-join (T1 hash-join T2)) hash-join T4

    t1作为build表和T2做hash_join,然后t3作为build表和t1,t2的结果集作hash_join,在把t3,t1,t2的结果集作build表和t4做hash_join
    通过sql可以写为

    MYDB@MYDB10G >select
      2  /*+
      3  ordered
      4  use_hash(t2)
      5  use_hash(t3)
      6  swap_join_inputs(t3)
      7  use_hash(t4)
      8  no_swap_join_inputs(t4)
      9  */
    10  * from t1,t2,t3,t4
    11  where t1.object_id=t2.object_id
    12  and t2.object_name=t3.object_name
    13  and t3.owner=t4.owner
    14  and t4.owner='MYDB'
    15  /
    已用时间:  00: 00: 00.07

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

    -------------------------------------------------------------------------------------
    | Id  | Operation            | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |      |  2137 |   801K|       |   182   (2)| 00:00:03 |
    |*  1 |  HASH JOIN           |      |  2137 |   801K|       |   182   (2)| 00:00:03 |
    |*  2 |   HASH JOIN          |      |    52 | 14976 |       |   167   (2)| 00:00:03 |
    |*  3 |    TABLE ACCESS FULL | T3   |    40 |  3840 |       |    15   (0)| 00:00:01 |
    |*  4 |    HASH JOIN         |      | 11651 |  2184K|  1232K|   151   (1)| 00:00:02 |
    |   5 |     TABLE ACCESS FULL| T1   | 11651 |  1092K|       |    15   (0)| 00:00:01 |
    |   6 |     TABLE ACCESS FULL| T2   | 11652 |  1092K|       |    15   (0)| 00:00:01 |
    |*  7 |   TABLE ACCESS FULL  | T4   |    41 |  3936 |       |    15   (0)| 00:00:01 |
    -------------------------------------------------------------------------------------

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

       1 - access("T3"."OWNER"="T4"."OWNER")
       2 - access("T2"."OBJECT_NAME"="T3"."OBJECT_NAME")
       3 - filter("T3"."OWNER"='MYDB')
       4 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
       7 - filter("T4"."OWNER"='MYDB')

    Note
    -----
       - dynamic sampling used for this statement

     
    说明:
    ordered表示依据from后面写的表的顺序来做联结~
    写hints,分开些思路清晰~ ordered后 from t1 ,t2 ,t3 ,t4说明首先使用t1做驱动表来连接t2,如何连接呢?看后面的hint use_hash(t2)
    代表连接t2的方式是hash_join;然后用use_hash(t3)表示连接t3的方式是hash-join,那么谁作build表呢?看后面的swap_join_inputs(t3)代表t3作build表和t1-t2的结果集作连接....依此类推~

    标准的hint就应该这么写~ use_hash(x,y,z)这样的写法是不规范,这样只是说出了x,y,z地联接方式
    ordered 是陈旧的hints,leading是用来代替ordered的~ leading不要求sql的写法(from后面的顺序不要求),直接可以在leading中定义连接顺序~
    leading和ordered不能一起使用,也没必要一起使用~
    至于"能不能举个Ordered不能实现而要用Leading的例子",上面已经说了,from后面的不能被修改的情况下可以使用leading.用法google一下,一大堆文档
    针对leading使用:
    10g中对leading做了加强~ 可以直接在后面写多表的连接顺序了,也就是说使用leading不需要from后面的固定顺序了
    MYDB@MYDB10G >select
      2     /*+
      3     leading(t1 t2 t3 t4)
      4     use_hash(t2)
      5     use_hash(t3)
      6     swap_join_inputs(t3)
      7     use_hash(t4)
      8     no_swap_join_inputs(t4)
      9     */  * from t3,t4,t2,t1
    10   where t1.object_id=t2.object_id
    11   and t2.object_name=t3.object_name
    12   and t3.owner=t4.owner
    13   and t4.owner='MYDB'
    14  /
    已用时间:  00: 00: 00.01

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

    -----------------------------------------------------------------------------
    | Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |      |  2069 |   179K|    57   (4)| 00:00:01 |
    |*  1 |  HASH JOIN           |      |  2069 |   179K|    57   (4)| 00:00:01 |
    |*  2 |   HASH JOIN          |      |    50 |  3100 |    38   (3)| 00:00:01 |
    |*  3 |    TABLE ACCESS FULL | T3   |    40 |  1080 |    18   (0)| 00:00:01 |
    |*  4 |    HASH JOIN         |      |    82 |  2870 |    20   (5)| 00:00:01 |
    |   5 |     TABLE ACCESS FULL| T1   | 11584 |   248K|    16   (0)| 00:00:01 |
    |   6 |     TABLE ACCESS FULL| T2   |    82 |  1066 |     3   (0)| 00:00:01 |
    |*  7 |   TABLE ACCESS FULL  | T4   |    41 |  1107 |    18   (0)| 00:00:01 |
    -----------------------------------------------------------------------------

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

       1 - access("T3"."OWNER"="T4"."OWNER")
       2 - access("T2"."OBJECT_NAME"="T3"."OBJECT_NAME")
       3 - filter("T3"."OWNER"='MYDB')
       4 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
       7 - filter("T4"."OWNER"='MYDB')

    MYDB@MYDB10G >select
      2     /*+
      3     ordered
      4     use_hash(t2)
      5     use_hash(t3)
      6     swap_join_inputs(t3)
      7     use_hash(t4)
      8     no_swap_join_inputs(t4)
      9     */  * from t1,t2,t3,t4
    10   where t1.object_id=t2.object_id
    11   and t2.object_name=t3.object_name
    12   and t3.owner=t4.owner
    13   and t4.owner='MYDB'
    14  /
    已用时间:  00: 00: 00.00

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

    -----------------------------------------------------------------------------
    | Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT     |      |  2069 |   179K|    57   (4)| 00:00:01 |
    |*  1 |  HASH JOIN           |      |  2069 |   179K|    57   (4)| 00:00:01 |
    |*  2 |   HASH JOIN          |      |    50 |  3100 |    38   (3)| 00:00:01 |
    |*  3 |    TABLE ACCESS FULL | T3   |    40 |  1080 |    18   (0)| 00:00:01 |
    |*  4 |    HASH JOIN         |      |    82 |  2870 |    20   (5)| 00:00:01 |
    |   5 |     TABLE ACCESS FULL| T1   | 11584 |   248K|    16   (0)| 00:00:01 |
    |   6 |     TABLE ACCESS FULL| T2   |    82 |  1066 |     3   (0)| 00:00:01 |
    |*  7 |   TABLE ACCESS FULL  | T4   |    41 |  1107 |    18   (0)| 00:00:01 |
    -----------------------------------------------------------------------------

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

       1 - access("T3"."OWNER"="T4"."OWNER")
       2 - access("T2"."OBJECT_NAME"="T3"."OBJECT_NAME")
       3 - filter("T3"."OWNER"='MYDB')
       4 - access("T1"."OBJECT_ID"="T2"."OBJECT_ID")
       7 - filter("T4"."OWNER"='MYDB'
  • 相关阅读:
    开源天气预报api整理
    Android gradle 相关配置
    Android Base64转图片
    【转】数据加密算法详解
    【转】零基础学习Fiddler抓包改包
    【转】你所不知道的Android Studio调试技巧
    【转】Android Studio-1.2版本设置教程
    Android app应用多语言切换功能实现
    Android通用流行框架大全
    38个学习新技能的最佳网站
  • 原文地址:https://www.cnblogs.com/alen-liu-sz/p/12975749.html
Copyright © 2011-2022 走看看