ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle Hint提示

Oracle Hint提示

原创 Linux操作系统 作者:jiangmh_sun 时间:2011-09-05 10:03:23 0 删除 编辑

/*+ USE_HASH(TABLE) */ use_hash提示对指定的标志性一个散列连接。

将指定的表与其他行源通过哈希连接方式连接起来.
        从本质上讲,散列连接是Oracle用以驱动表(最小的表,where 子句中的第一个表)向RAM区中装载纪录
    的方法,RAM区是由hash_area_size初始化参数定义的。
        然后,Oracle使用散列的方法定位第二小的表中的纪录。在两个表都非常大的情况下,散列连接通常
    与并行查询结合使用。

    例如:
       SELECT /*+ USE_HASH(TA,TB) parallel(TA,4) parallel(TB,4) */
         FROM BSEMPMS TA,
              BSDPTMS TB
        WHERE TA.DPT_NO=TB.DPT_NO;
    分析:
       装入小表(BSEMPMS)到RAM,使用RAM中的行ID进行散列访问大表(BSDPTMS)。
    说明:
       散列连接通常快于嵌套循环连接,特别是在驱动表已经在查询的where子句中过滤,只剩下少量记录的
       情况。
    前提:
       A、检查初始化参数
          确保正确设置optimozer_index_cost_adj、hash_multiblock_io_count、optimozer_max_permutations
          和hash_area_size参数。
       B、检察驱动表
          确保最小的表作为驱动表(from子句中的第一个表).这是因为散列连接使用驱动表创建内存数组。
       C、分析CBO统计资料
          确保对表和(或)连接表字段的统计资料进行过正确的分析。
       D、检察分布不均匀的字段
          推荐仅对不均匀的分配使用字段矩形图。
       E、检察RAM区
          确保hash_area_size大到可以容纳内存中较小的表。否则,Oracle必然会将写入temp表空间,降低
          散列连接的速度。

/*+ USE_MERGE(TABLE) */ 将指定的表与其他行源通过合并排序连接方式连接起来

use_merge提示强制执行—个排序合并操作。排序合并操作通常与并行查询结合使用,因为排序合并连接对
   表执行全表扫描。排序合并连接最适用于生成大型结果集的查询.
       例如日常报表和表细节总结查询,或用来处理不使用连接主键索引的表。

    例如:
    SELECT /*+ USE_MERGE(BSEMPMS,BSDPTMS) */
      FROM BSEMPMS,
           BSDPTMS
     WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
    注意:
        排序合并连接并不使用索引来连接这些表。在大多数情况下,索引访问会更快。但是排序合并连接
    可能最适合于不使用where子句的大连接表,或表中无索引的查询。

/*+ USE_NL(TABLE) */将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.

强制对目标表执行嵌套循环连接。与其他方式的连接提示不同,use_nl提示只需驱动表的名称(使用CBO时,
   from子句的第一个表)。嵌套循环连接是最古老的连接方式,它几乎总是基于规则的优化方式(也就是RULE
   提示)共同使用。

    例如:
    SELECT /*+ORDERED USE_NL(BSEMPMS)*/
           BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM
      FROM BSEMPMS,
           BSDPTMS
     WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

/*+ START */ 强制使用星型查询计划

前提是查询中存在至少三个表,而且在事实表中存在恰当的索引。Star提示比传统的连接方式快得多,传统
   的连接方式首先将最小的引用表与事实表连接,再将其他的引用表与中间生成表连接。
   前提:
      A、必须存在连接在一起的至少三个表,其中有——个大的事实表和几个小维表。
      B、在事实表的字段上必须存在一个索引,这些字段将是每个表的连接主键。从Oracle8i开始,你需要
         使用位图索引,而不是连接在一起的索引。
      C、你必须检验执行计划,以确保在执行连接时使用嵌套循环操作。

   原理:
      1、将维表装入内存
      2、将事实表使用连锁索引连接
      3、产生查询结果

/*+ MERGE_AJ */ 放到NOT IN 子查询中反向连接

在使用全表访问比索引访问更好的情况下,我们可以在not in子查询中使用merge_aj提示,以方便于执行
   反向连接。
   警告:
      只有在not in 子句中要求的字段有非空限制的时候,反连接提示merge_ah和hash_aj才起作用。
   
   例如:
      select dname
        from dept
       where deptno not in (select /*+ merge_aj */ deptno
                              from emp
                             where job='SALESMAN');

/*+ HASH_AJ */ 放到NOT IN 子查询中进行散列反向连接

/*+ INDEX_JOIN(TABLE INDEX_NAME) */ 提示明确命令优化器使用索引作为访问路径.

例如:
   SELECT /*INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/
          Sal,
          Hiredate
     FROM Bsempms
    WHERE Sal < 60000;

/*+ ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,... */将几个单列索引的扫描合起来.

如果表拥有非惟一的单独字段索引,而且你期望使用多个索引服务于该查询,那么可以使用and_equal
    提示。它将合并这些索引,并使这些单独索引操作时就象耽搁连锁索引一样。
   
    前提:
       需要指定表名和至少两个索引名,但是索引名不能操作5个。
    例如:
    SELECT /*+ INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX) */
      FROM Bsempms
     WHERE Emp_No = 'SCOTT'
       AND Dpt_No = 'TDC306';

/*+ no_index */ 提示强制优化器忽略索引的存在


Hash join
它的連接方式﹐Oracle將第一個表加載入內存﹐使用一種Hash技
朮﹐連接第二個表. 顯然驅動表應該選擇兩者中的較小者。
因為CBO總是傾向于把HASH連接放在次要地位﹐我們可以用
USE_HASH提示﹐強制優化器使用HASH連接方式。由于HASH算
法的使用﹐索引的存在對性能的影響不是很大。

Nested loop

即嵌套循環連接﹐是一種是最基本的表連接方式﹐在嵌套循環
中﹐首先從驅動表讀取記錄﹐然后把結果集與第二個表進行比較
連接﹐如圖所示,這一切都是通過索引來進行的﹐如果沒有索引﹐
連接成本會大大地增加。
在考慮連接順序時﹐應該把最小的表作為驅動表。
在內部表上建有可用的索引的時候﹐應該首先考慮使用Nested Loop。

Sort merge join
它不使用索引﹐它用全表掃描獲得兩個數據集合﹐然后將它們
分別排序后﹐合并成為一個最終的結果集。
注意到排序合并連接中并沒有使用索引是非常重要的。在大多數
情況下﹐通過索引訪問更快一些﹐但是當連接表中需要有大量資料
的處理和返回﹐大量的全表掃描﹐或者表上沒有建立索引的話﹐可
以考慮使用Sort merge join。

* 表連接優化實例

曾經在一個ERP維護中遇到過這樣一個典型問題﹐有一個比較
復雜的SQL﹐其中由多個關聯了十几個大表的視圖JOIN而成﹐咝?
一次花几個小時的時間。后來經過仔細觀察執行計划﹐發現優化器
在處理上述的几個大的結果集關聯的時候﹐使用的是嵌套循環。眾
所周知﹐嵌套循環需要用到索引﹐否則效率會很低﹐而几個數據集
關聯時是不可能有索引的﹐咝屑競

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26244658/viewspace-706644/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2011-09-05

  • 博文量
    7
  • 访问量
    21640