EXADATA智能扫描

提要:
查询特定的要求:
智能扫描只可用于完整的表或索引扫描。
智能扫描只能用于直接路径读取:
直接路径读取会自动用于并行查询。
直接路径读取能够用于串行查询。
默认状况下不使用它们进行小型表的串行扫描。
使用 _serial_direct_read=TRUE 可强制执行直接路径读取。算法

为了查询能够得到Exadata卸载能力的优点,优化器必须决定使用全表扫描或者快速全索引扫描来执行语句,这里的用词比较笼统,通常来讲,这两个词对应的是执行计划中的TABLE ACCESS FULL和INDEX FAST FULL SCAN。在Exadata中,这些相似的操做的命名作了些许更改以代表访问的是Exadata存储。新的操做名称是TABLE ACCESS STORAGE FULL和INDEX STORAGE FAST FULL SCAN。请注意,也有一些细微的变化,好比 MAT_VIEW ACCESS STORAGE FULL事件也表示可使用智能扫描。不过你应该知道,事实上就算执行计划里面显示 TABLE ACCESS STORAGE FULL操做,也并不意味着查询就必定执行了智能扫描,它仅仅意味着前提已经知足。咱们将在本章稍后探讨如何确认一个语句是否确实经过智能扫描实现了卸载操做。数据库

直接路径读是什么意思?下面两段话能够解释
智能扫描除了必须是全扫描以外,还须要读取操做是经过Oracle直接路径读取机制来执行的。直接路径读取已经存在很长一段时间了,传统上,这种读取机制是被服务于并行查询的从属进程(Slave Process)使用的。由于并行查询最初预计将用于访问很是大量的数据(一般大到没法所有放入Oracle缓冲区),因此决定并行从属进程直接读取数据,而后放入本身的内存中(也被称为程序全局区或者PGA)。直接路径读取机制彻底跳过了标准的将数据库放入缓冲区这样的Oracle缓存机制,这对海量数据是很是有效的,由于它消除了那些额外的没有帮助的工做(缓存全表扫描获取到的却又可能不会被再次用到的数据),让这些块不至于将其余的数据块刷新出缓冲区。像咱们以前提到的,kcfis(Kernel File Intelligent Storage)函数是被kcbldrget( Kernel Block Direct Read GET)函数调用的,因此,智能扫描只有在使用直接路径读取机制的时候才会执行。缓存

除了并行从属进程,只要条件容许,直接路径读取也可能用在非并行SQL语句中。有一个隐含参数_SERIAL_DIRECT_READ能够控制此功能。当此参数设置为默认值AUTO时,Oracle自动判断是否要为非并行扫描使用直接路径读取。计算基于几个因素,包括对象大小、Buffer Cache大小,以及在Buffer Cache中已存在了多少该对象的数据块。另外,还有一个隐含参数(_SMALL_TABLE_THRESHOLD)定义了若是要使用串行直接路径读取,那么表至少要为多大。对于非串行扫描决定是否要使用直接路径读取机制的算法并未公开,虽然串行直接路径读取的功能早已存在,可是只是在最近才成为比较广泛的现象。Oracle数据库11gR2在计算是否对于非并行扫描使用直接路径读取上作了一些修改,新修改的算法使Oracle 11gR2比之前的数据库版本要更频繁地采用直接路径读取。这也许是由于有了Exadata智能扫描,所以但愿尽量地触发直接路径读取,可是这样的算法在非Exadata平台上可能略显激进。函数

备注 My Oracle Support文档:793845.1中包含以下表述。
在11g中,关于在串行表扫描中是使用直接路径读取仍是使用缓存读取,咱们作了探索性的改动。在10g中,对于大表的串行扫描默认是经过缓存的,在11g中,决定是直接读取仍是经过缓存读取,要基于表大小、缓冲区大小和其余多种统计信息。由于避免了闩锁(Latche),所以直接路径读取比离散读(Scattered Read)更快,对其余进程影响更小。性能


彻底索引扫描和快速彻底索引扫描的区别:优化

彻底索引扫描: 这个性能感受是最差的,只能单块读取,并且还要经过表去得到数据,可是由于他是按索引的顺序读取的,因此再也不须要排序. 好比 select * from table order by name, 若是name 上有索引,很显然这个时候通常有2个计划, 第一个,全表扫描,而后sort, 还有一个状况,彻底索引扫描就OK. 由于此时不须要排序了.
索引全扫描是根据叶节点链来进行的。进行索引全扫描首先要从根开始,找到叶节点链上的第一个数据块,而后沿着叶节点链进行扫描,因为叶节点链是根据索引键值排序的,所以这样扫描出来的数据自己就是排序的,数据读出后不须要再次排序。这种扫描方式和索引快速全扫描相比,首先要找到索引的根,而后经过枝节点找到第一个叶节点,而后再顺着叶节点链扫描整个索引。索引全扫描的IO成本比索引快速全扫描要大不少,读取根节点和叶节点的成本相对不大,不过因为顺着叶节点链扫描整个索引的时候没法使用多块读,而只能使用单块读,所以这种扫描方式的IO开销要远大于索引快速全扫描。这种索引扫描,咱们若是对会话进行跟踪,会发现大量的db file sequential read等待。对象

快速彻底索引扫描:
属先这个扫描是不用经过表获得数据的.这个是重点. 那么不经过表获得数据,很明显只能经过索引获得数据了. 那就更明显了,那你要拿的字段必须在索引中,否者如何不经过表的到数据?一般好比:select name from table; 若是name上有索引,有可能走FFS.可是若是是select name,id from table,假如id没有索引,那么无论怎么样,都是不可能走FFS的.对索引的扫描能够根据该索引的extent来进行,采用多块读的方式进行。所以在这类操做中,咱们能够看到会话会大量的出现db file scattered read等待。
后者是咱们但愿在EXADATA上出现的索引扫描方式排序

相关文章
相关标签/搜索