一般在混合型环境中,大表在进行全表扫描或者走并行的时候一般会出现direct path read等待事件,如果在OLTP或者纯粹的DSS环境中,出现大量的direct path read直接路径读取,这样就有问题了,尤其是一些流水线的批处理系统中,会导致大量的free buffer wait等(因为direct path reads会导致oracle执行object level checkpoint将所有目标对象的脏块写入磁盘,然后将这些块从磁盘读取到进程的PGA,如果有未提交的事务,还必须使用PGA构造读一致性块缓冲。所以parallel是把双刃剑,用的不好,系统性能会很慢,尤其是在跑批系统中,增加了大量不必要的物理读写,要想跑的飞快,cpu利用起来,应用层的fork-join线程池设计极大的决定了系统的性能)。一般在OLTP中,都是事务型的sql,如果想sql执行效率,那么最好从内存当中读取数据,直接从数据文件中读取,后果可想而知了。这里就可能需要我们禁用direct path read。

在oracle 11.2之前,只要没有设置_serial_direct_read为true,同时没有指定并行执行,oracle会将HWM以下的块读入buffer cache。如果走了并行执行,意味着所有的表都会导致direct read,即使表不大也如此。

从11.2开始,oracle默认会自动决定要不要在非并行执行的时候绕过buffer cache并使用direct path read(为什么这是合适的呢,举个例子,假设有张表有1亿条数据,平均纪录长度200,全表扫描意味着20G的buffer cache,而服务器本身可能只配置了64G,很明显一张1亿条记录的表不太可能是所有记录都经常要访问的,但是其中的1/10经常访问是可能的,此时如果这个表没有分区显然是不合理的)。同时,更重要的是,我们可以通过参数控制并行查询的时候对某些表的扫描可以走buffer cache,而不是direct read。

oracle根据几个参数决定全表扫描的时候是否走直接路径读,首先是_small_table_threshold隐含参数,它决定oracle认为的小表阈值(同时,读取少于该值的parallel将使用buffer cache),每个环境和版本都可能不同,默认值约为默认值是db cache size的2%大小。如下:

_serial_direct_read值控制非并行执行的时候是否允许走直接读。默认情况下,如果表大于_small_table_threshold*5,则全表扫描的时候自动会被调整为direct read,也就是buffer cache的1/10左右(这个算大、也不算大)。

这个值其实应该被启用,这是对的,但是应该合理设置_small_table_threshold的阈值以最小化不必要的物理io。

可以通过两种方式是禁用直接读,如下:

SQL> alter system set event='10949 TRACE NAME CONTEXT FOREVER, level 1' scope=spfile;
System altered SQL> alter session set "_serial_direct_read"=false;
Session altered SQL>
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
2 FROM SYS.x$ksppi x, SYS.x$ksppcv y
3 where x.indx = y.indx
4 AND (x.ksppinm = '_small_table_threshold' or
5 x.ksppinm = '_serial_direct_read');
NAME VALUE DESCRIB
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
_small_table_threshold 30338 lower threshold level of table size for direct reads
_serial_direct_read FALSE enable direct read in serial SQL>

还有一个参数 _very_large_object_threshold 用于设定(MB单位)不使用direct path read方式的上限,这个参数需要结合10949事件共同发挥作用。10049和_very_large_object_threshold参数一起的时候,只要_very_large_object_threshold小于目标表大小*0.8或者buffer cache*5,就可以不走direct path read。所以,要想完全禁用非并行执行时的直接路径读,只要将_very_large_object_threshold设置的足够大即可,不过不建议超过20%*buffer cache(否则要么是分区没使用或者不合理)。

所以在并行和串行之间存在一个矛盾点,这个矛盾点只能通过高配置服务器比如256GB/128C+良好的表结构设计或者应用层面的分而治之来解决。

当然,我没有仔细去测,最近太忙,没有时间一一去验证,后面会仔细验证效果如何。

这给帖子写的不错,可以参考下http://www.itpub.net/thread-1815281-1-1.html

参考:http://oracleinaction.com/direct-reads-11g/

oracle 11g禁用和强制direct path read的更多相关文章

  1. Oracle 11g 禁用 SQL Tuning Advisor 与 auto space advisor

    生产上有一套11g数据库alert.log报错ORA-16957: SQL Analyze time limit interrupt.  查询MOS相关文档Troubleshooting: ORA-1 ...

  2. 关闭Oracle 11g的DPR特性

    关闭Oracle 11g的DPR(Direct Path Read)特性 查看event参数值: SQL> show parameter event NAME TYPE VALUE ------ ...

  3. AWR实战分析之----direct path read temp

    http://blog.sina.com.cn/s/blog_61cd89f60102eej1.html 1.direct path read temp select TOTAL_BLOCKS,USE ...

  4. Oracle 11g全表扫描以Direct Path Read方式执行

    在Oracle Database 11g中有一个新特性,全表扫描可以通过直接路径读的方式来执行(Direct Path Read),这是一个合理的变化,如果全表扫描的大量数据读取是偶发性的,则直接路径 ...

  5. oracle 11G direct path read 很美也很伤人

    direct path read在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这样的全表扫描就是物理读了. 在10g中,都是通过gc buffer来读 ...

  6. Oracle 11g direct path read 等待事件的理解

    在Oracle 11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这样的全表扫描就是物理读了. 在10g中,都是通过gc buffer来读的,所以不存在di ...

  7. oracle 11G direct path read 非常美也非常伤人

    direct path read 在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这种全表扫描就是物理读了. 在10g中,都是通过gc buffer来读 ...

  8. 【Oracle】11g direct path read介绍:10949 event、_small_table_threshold与_serial_direct_read

    转自刘相兵老师的博文: http://www.askmaclean.com/archives/11g-direct-path-read-10949-_small_table_threshold-_se ...

  9. Oracle 11g新特性direct path read引发的系统停运故障诊断处理

    黎俊杰 | 2016-07-28 14:37 声明:部分表名为了脱敏而用XX代替 1.故障现象 (1)一个业务系统输入用户名与密码后无法进入首页,表现为一直在运行等待,运行缓慢 (2)整个系统无法正常 ...

随机推荐

  1. android studio 设置安装不占用C盘

    我们知道,android studio 安装会占用大量的空间,比如我们我们将andriod status 安装到了D:\IDE\Android Studio这里,但是你会发现,在编译出包过程中,C盘的 ...

  2. statement对象与sql语句(新手)

    本篇介绍读上篇代码中的疑惑点 实现简单网页上对数据内容进行增删改查,需要用到三个部分:jsp网页前端部分+java后台程序+数据库表 一.创建一个Statement (用于在已经建立数据库连接的基础上 ...

  3. java框架常见的面试题

    1.谈谈你对MVC的理解 MVC是Model—View—Controler的简称.即模型—视图—控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开. MVC中的模型.视图.控制器 ...

  4. cocos2d JS-(JavaScript) 几种循环遍历对象的比较

    通常我们会用循环的方式来遍历数组.但是循环是 导致js 性能问题的原因之一.一般我们会采用下几种方式来进行数组的遍历: 方式1: for in 循环: var arr = [1,2,3,4,5]; v ...

  5. Unity3d vector3.forward和transform.forward的区别!

    原文连接: http://blog.csdn.net/kaluluosi111/article/details/17206655 在unity3d中有2个forward,一个是vector3.forw ...

  6. 10.用js下载文件(需要后端链接)

          用js下载文件 PS:本文说的,并非如何用js创建流.创建文件.实现下载功能. 而是说的:你已知一个下载文件的后端接口,前端如何请求该接口,实现点击按钮.下载文件到本地.(可以是zip啦. ...

  7. 实时计算DStream下求平均值(reduceByKey or combineByKey)

    对NC市的卡口数据进行分析,大概所有卡口每15秒接入的有效数据在3000条左右,现在产品经理要求对这些数据进行拥堵分析,通过两个卡口之间的车辆行驶时长来判断道路的拥堵情况.具体算法不展开.其中我需要做 ...

  8. spark2.2.1 sql001

    package sql import org.apache.spark.sql.SparkSession import org.apache.spark.SparkContext object Par ...

  9. Java类访问控制

      public protected default private 本类 可见 可见 可见 可见 本类所在包 可见 可见 可见 不可见 其他包中的子类 可见 可见 不可见 不可见 其他包中的非子类 ...

  10. 三 js语句

    /** * Created by Administrator on 2017/12/24. * 1.顺序语句 * 2.选择语句 if else swtich case * 3.循环语句 for whi ...