[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. http-长连接

    1. 短链接 http1.0 -- 1个请求-响应过程会创建且1个新的连接 2. 长连接 http1.1 -- 同域下可以创建1个tcp连接,多个请求在同一个tcp上串行处理请求 http2.0 -- ...

  2. [转帖]【SQL Server】varchar和nvarchar的基本介绍及其区别

    https://www.cnblogs.com/zhaoyl9/p/15243556.html varchar(n) 长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 ...

  3. [转帖]Unix Domain Socket– IPC通信机制

    什么是Unix Domain Socket 基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loopba ...

  4. [转帖]VMware ESXi 各版本号对照表

    本博文转自以下链接: VMware ESXi Release and Build Number History | virten.net vSphere ESXi 7.0 Name Patch Dat ...

  5. [转帖]crash工具分析Kdump下vmcore文件常用命令总结(三)(实例易懂)

    一.简介 本文主要介绍使用crash工具对kdump生成的vmcore文件进行分析,解析常见的crash命令,前面已讲述两章关于Kdump的内容,读者感兴趣可以点击下面的链接: 1.Kdump调试机理 ...

  6. [转帖]linux下 进程io队列,IO队列和IO调度

    IO体系概览 先看看本文主题IO调度和IO队列处于整个IO体系的哪个位置,这个IO体系是非常重要的,了解IO体系我们可以对整个IO过程有个全面的认识.虽然一下两下并不清楚IO体系各个部分的细节,但是我 ...

  7. [转帖]【JVM】JVM概述

    1.JVM定义 JVM 是Java Virtual Machine(JVM )的缩写,Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令进行执行,这样实现了Java"一次编译, ...

  8. dd命令的简单学习

    dd命令简介 dd Copy a file, converting and formatting according to the operands. dd 可以理解为是 disk dump 磁盘转储 ...

  9. Linux上面批量更新SQLSERVER SQL文本文件的办法

    1. 今天同事让帮忙更新几个SQL文件.. 本着自己虽然low 但是不能太low的想法, 简单写一个 shell 脚本来执行. 2. 因为我的linux 里面都安装了 sqlcmd 的工具 所以办法就 ...

  10. 【DS】【AtCoder】Pakencamp 2022 Day2 H

    2023.6.30 Problem Link 有 \(n\) 个帮派在打架,每个帮派有一个大小 \(a_i\),每相邻两个帮派有一个仇恨度 \(b_i\).现在有 \(Q\) 次单点修改 \(a_i\ ...