[English]
搜索Internet 搜索 HelloDBABA
  Oracle技术站。email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com      

Oracle 10gR2新SQL提示——opt_param

[English]

作者: fuyuncat

来源: www.HelloDBA.com

日期: 2009-03-16 14:56:22

分享到 

我们知道,在Oracle中存在许多参数能够影响SQL的查询计划,如hash_join_enabled、optimizer_index_cost_adj、_optim_peek_user_binds。正确调整这些参数能够解决不少SQL所引起的性能问题。但是,在调整这些参数时需要注意一点,他们是对整个实例其作用的。他们的影响范围如此之大,以至于我们可能通过调整这些参数解决某一条SQL的问题,但是参数的调整却会给其他SQL带来负面影响。有没有办法使某个参数只针对某条语句有一个特殊的数值,而对系统没有影响呢?Oracle 10gR2就提供了一个这样的提示——opt_param。

看下这个提示的用法:/*+opt_param(<parameter_name>[,] <parameter_value>)*/。这个提示的作用就是使我们在某条语句中指定某个系统参数值。

下面看下这个参数是如何起作用的:

SQL> set autot trace
SQL> select t1.object_id, t2.tablespace_name
  2  from t_test1 t1, t_test2 t2
  3  where t1.object_name = t2.table_name;
 
2536 rows selected.
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3541962439
 
------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |  3348 |   170K|   169   (2)| 00:00:03 |
|*  1 |  HASH JOIN         |         |  3348 |   170K|   169   (2)| 00:00:03 |
|   2 |   TABLE ACCESS FULL| T_TEST2 |  2072 | 51800 |    17   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| T_TEST1 | 47582 |  1254K|   150   (1)| 00:00:02 |
------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("T1"."OBJECT_NAME"="T2"."TABLE_NAME")
 
 
... ...
 
SQL> select /*+opt_param('hash_join_enabled', 'false')*/ t1.object_id, t2.tablespace_name
  2  from t_test1 t1, t_test2 t2
  3  where t1.object_name = t2.table_name;
 
2536 rows selected.
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 2273132659
 
---------------------------------------------------------------------------------
| Id  | Operation           | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)|Time|
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |         |  3348 |   170K|       |   840   (1)| 00:
00:11 |
|   1 |  MERGE JOIN         |         |  3348 |   170K|       |   840   (1)| 00:
00:11 |
|   2 |   SORT JOIN         |         |  2072 | 51800 |   168K|    34   (3)| 00:
00:01 |
|   3 |    TABLE ACCESS FULL| T_TEST2 |  2072 | 51800 |       |    17   (0)| 00:
00:01 |
|*  4 |   SORT JOIN         |         | 47582 |  1254K|  3384K|   806   (1)| 00:
00:10 |
|   5 |    TABLE ACCESS FULL| T_TEST1 | 47582 |  1254K|       |   150   (1)| 00:
00:02 |
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   4 - access("T1"."OBJECT_NAME"="T2"."TABLE_NAME")
       filter("T1"."OBJECT_NAME"="T2"."TABLE_NAME")
 
... ...
 

在我们的系统中存在一个案例,就是通过这个提示来解决的。案例的背景描述如下:该系统是一个5*24系统,周末2天是系统维护时间。在系统中存在一个作业,会执行下面一条语句:

 SELECT COUNT(A.CARRIER_ID)
 FROM CSS_TP_SHMT_QUEUE A,
           CSS_TP_SHMT_QUEUE_ACTIVITY B
 WHERE A.SHMT_QUEUE_STATUS_CDE = :B3
 AND B.SHMT_QUEUE_ID = A.SHMT_QUEUE_ID
 AND B.ACTIVITY_STATUS_CDE = :B2
 AND A.CARRIER_ID = :B1
 AND A.REC_CREAT_DT > SYSDATE - 30
 AND ROWNUM <= 1;

我们发现有时这条语句在生产系统上跑的性能非常差,占用单颗CPU100%,运行时间达到几个小时。通过v$sql_plan我们获取到该语句在生产系统上的查询计划如下:

db01> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
  2  object_name||' '||decode(id, 0, 'Cost='||cost) "Query Plan_Table"
  3  from v$sql_plan
  4  start with id = 0
  5  and hash_value = 380787837
  6  connect by prior id = parent_id
  7  and hash_value = 380787837;
 
Query Plan_Table
------------------------------------------------------------------------------------------------------------
SELECT STATEMENT   Cost=3
  SORT AGGREGATE
    COUNT STOPKEY
      NESTED LOOPS
        TABLE ACCESS BY INDEX ROWID CSS_TP_SHMT_QUEUE
          INDEX UNIQUE SCAN CSS_TP_SHMT_QUEUE_PK
        INDEX RANGE SCAN CSS_TP_SHMT_QUEUE_ACTIVITY_IX4

通过分析,这个查询计划是存在问题的,它错误的选择了索引“CSS_TP_SHMT_QUEUE_PK”。我们将相关两张表的统计信息做了更新,但发现这条Top SQL并没有得到改观,还存在生产系统上。

当我们给语句带上参数数值在数据库上进行trace时,却发现它产生了正确的查询计划并在几秒钟之内返回了结果:

db01> SET TIMING ON
db01> SET AUTOT TRACE
db01> 
db01> SELECT count(a.carrier_id)
  2  FROM   css_tp_shmt_queue a, css_tp_shmt_queue_activity b
  3  WHERE  a.shmt_queue_status_cde = 'E'
  4  AND    b.shmt_queue_id            = a.shmt_queue_id
  5  AND    b.activity_status_cde   = 'EC'
  6  AND    a.carrier_id      = 1
  7  AND    a.rec_creat_dt             > SYSDATE - 30
  8  AND    rownum <= 1;
 
Elapsed: 00:00:04.01
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3859675621
 
------------------------------------------------------------------------------
| Id  | Operation            | Name                           | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                                |     1 |    19 |   169   (2)| 00:00:03 |
|   1 |  SORT  AGGREGATE     |                                |     1 |    19 |   150   (1)| 00:00:02 |
|   2 |   COUNT  STOPKEY     |                                |     1 |  8652 |   169   (2)| 00:00:03 |
|   2 |    NESTED LOOPS      |                                |  3348 |    10K|   169   (2)| 00:00:03 |
|   3 |     INDEX RANGE SCAN | CSS_TP_SHMT_QUEUE_IDX6         |   234 |  8719 |    17   (0)| 00:00:01 |
|   4 |     INDEX RANGE SCAN | CSS_TP_SHMT_QUEUE_ACTIVITY_IX4 |    21 |   134 |   150   (1)| 00:00:02 |
------------------------------------------------------------------------------
 
 
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=9 Card=1 Bytes=28)
   1    0   SORT (AGGREGATE)
   2    1     COUNT (STOPKEY)
   3    2       NESTED LOOPS (Cost=9 Card=18465 Bytes=517020)
   4    3         INDEX (RANGE SCAN) OF 'CSS_TP_SHMT_QUEUE_IDX6' (NON-
          UNIQUE) (Cost=15 Card=18294 Bytes=347586)
   5    3         INDEX (RANGE SCAN) OF 'CSS_TP_SHMT_QUEUE_ACTIVITY_IX4' (NON-UNIQUE)

因此,我们初步判断这是由于bind peeking所导致的,因为每周系统维护后,周一会传来一新的数据需要处理,这些数据作为参数传入函数后,根据bind peeking机制,SQL在第一次执行时会根据传入的数据来计算出查询计划。但是由于数据是无法控制的,第一次传入的数据并非典型数据,从而导致优化器采用了不理想的查询计划(关于bind peeking对查询计划的影响,可以参见文章《什么时候使用绑定变量性能反而更差》)。

当然,我们可以通过修改参数“_optim_peek_user_binds”来关闭bind peeking。但是,由于这个参数是实例级,我们无法预知这个参数的修改会对系统其他SQL造成什么影响。轻易改变生产数据库上的任何一个系统参数的DBA是鲁莽的,且后果是不可预知的。我们在这就可以通过使用Oracle提供的这个提示来强制使这条SQL来关闭bind peeking并不会对其他语句产生任何影响:

SELECT /*+opt_param('_optim_peek_user_binds', 'false')*/ COUNT(A.CARRIER_ID)
 FROM CSS_TP_SHMT_QUEUE A,
           CSS_TP_SHMT_QUEUE_ACTIVITY B
 WHERE A.SHMT_QUEUE_STATUS_CDE = :B3
 AND B.SHMT_QUEUE_ID = A.SHMT_QUEUE_ID
 AND B.ACTIVITY_STATUS_CDE = :B2
 AND A.CARRIER_ID = :B1
 AND A.REC_CREAT_DT > SYSDATE - 30
 AND ROWNUM <= 1;

Top

Copyright 2005,HelloDBA.Com 保留一切权利

申明by fuyuncat

Oracle 10gR2新SQL提示——opt_param的更多相关文章

  1. oracle 更改SQL提示

    在oracle里面修改SQL提示为数据库名称: SQL>set SQLPROMPT "TEST>"

  2. 解决PL/SQL Dev连接Oracle弹出空白提示框

    第一次安装Oracle,装在虚拟机中,用PL/SQL Dev连接远程数据库的时候老是弹出空白提示框,网上找了很久,解决方法也很多,可是就是没法解决我这种情况的. 没办法,只能自己研究,经过大概一天时间 ...

  3. Oracle 11g 中SQL性能优化新特性之SQL性能分析器(SQLPA)

    Oracle11g中,真实应用测试选项(the Real Application Testing Option)提供了一个有用的特点,叫SQL性能分析器(SQL Performance Analyze ...

  4. PL/SQL Dev连接Oracle弹出空白提示框的解决方法分享

    第一次安装Oracle,装在虚拟机中,用PL/SQL Dev连接远程数据库的时候老是弹出空白提示框,网上找了很久,解决方法也很多,可是就是没法解决我这种情况的. 出现这种问题,解决方法大概有这几种: ...

  5. Oracle 11g 新特性 --SQL Plan Management 说明

    Oracle 11g 新特性 --SQL Plan Management 说明 参见大神博主文章: http://blog.csdn.net/tianlesoftware/article/detail ...

  6. Oracle 10gR2 Dataguard搭建(非duplicate方式)

    Oracle 10gR2 Dataguard搭建(非duplicate方式) 我的实验环境: 源生产库(主库): IP地址:192.168.1.30 Oracle 10.2.0.5 单实例 新DG库( ...

  7. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part3:db安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 5.安装Database软件 5. ...

  8. Oracle 11g新特性

    文章转自网络 Oracle 11g于2007年7月11日美国东部时间11时(北京时间11日22时)正式发布,11g是甲骨文公司30年来发布的最重要的数据库版本,根据用户的需求实现了信息生命周期管理(I ...

  9. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...

  10. Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part2:clusterware安装和升级

    Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part2:clusterware安装和升级 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 3.安装Clus ...

随机推荐

  1. web-云部署上线

  2. [转帖]5 分钟学会写一个自己的 Prometheus Exporter

    https://cloud.tencent.com/developer/article/1520621学习一下怎么搭建呢.   去年底我写了一个阿里云云监控的 Prometheus Exporter, ...

  3. [转帖]Linux中的inode到底是什么

    https://www.jianshu.com/p/6aa4d7ef17de inode 是什么? 要了解 Linux 操作系统上的 inode 前,我们先来说说 Linux操作系统上的文件.对于 L ...

  4. [转帖]龙叔学ES:Elasticsearch XPACK安全认证

    https://juejin.cn/post/7081994919237287950 本文已参与「新人创作礼」活动,一起开启掘金创作之路. Elasticsearch往往存有公司大量的数据,如果安全不 ...

  5. SPECJVM2008 再学习

    SPECJVM2008 再学习 摘要 昨天的太水了 感觉今天有必要再水一点.. 存在的问题 默认进行启动 sunflow 必定过不去. 一般的解决办法要求进行重新编译 但是我不知道怎么下载源码... ...

  6. VCSA 添加新管理用户的方法

    VCSA 6.7 添加单独虚拟机管理员账户的方法 最近一次护网工作中,要求升级vCenter的版本, 所以比较无奈进行了相关的升级和设置, 管理员的分发与之前的vcenter的不太一致, 这里面简单记 ...

  7. echarts设置单位的偏移

    echarts 可以设置的echarts单位的偏移位置吗? 之前是知道echarts的X和Y是可以设置单位的. 但是设置单位的位置一直不好调整. 现在有时间,我们会回答一下上面标题的问题? echar ...

  8. webservice--WSDL文件生成本地的代理类

    我们在对应第三方接口时常用:项目上右键---->服务引用---->WCF Web Service,如下图的页面----->填好url后---->转到,就可以发现服务,生成代理类 ...

  9. RabbitMQ集成系统文章01---ABP VNext 分布式事务Event Bus 集成RabbitMQ

    1.在两个应用中都配置好要连接的RabbitMQ "RabbitMQ": { "Connections": { "Default": { & ...

  10. 『Echarts』简介

    目录 一.前言 二.『Echarts』简介 1. 什么是『Echarts』 三.数据可视化 四.『Echarts』 1.『Echarts』的作用 2.『Echarts』能绘制哪些图表 3.『Echar ...