oracle访问数据

来源:互联网 发布:迅龙数据恢复软件 mac 编辑:程序博客网 时间:2024/06/05 07:28

优化器在数据库的作用就是解析sql,确定访问数据的方法,然后确定其执行计划。

优化器要决定采用什么方式和方法访问目标就是数据库的核心

一般访问数据的方式有:单表,多表,索引等等


访问表的方法

全表扫描:访问表里所有的数据,会从该表占用的第一个区开始扫描,一直扫描到该标的高水位线,这个范围内所有的数据都要读取到。

1、使用多块读

2、执行时间不可控会随着目标表的数据量递增

3、占用大量的IO

4、要访问高水位线以下所有的块


ROWID扫描:oracle访问目标表里的数据,直接通过数据所在的ROWID定位数据。

ROWID表示的是oralce中的数据行记录所在的物理存储地址,实际上是和oracle中数据块里的行记录一一对应

1、它可以直接访问数据库里的数据

2、另一种是先去访问相关的索引,然后得到ROWID,再去访问表里的数据


访问索引的方法

这里所致的是Btree索引,其他索引暂不考虑

Btree索包含两种类型的数据块:一种是索引分支块,一种是索引叶子块

索引分之包含指向相应索引分支块和索引健值列,这个索引的键值列不一定就是完整的被索引键值,它可能只是被索引键值的前缀,只要oralce通过这些前缀

区分相应的索引分支块/列,这样oralce就能够既节省索引分支块的存储空间,又可以快速定位其下层的索引分支块/叶子块

Btree具有如下优势:

1、所有的索引叶子块都在同一层,即他们距离索引根节点的深度是相同的

2、oracle会保证所有的Btree索引都是自平衡的

3、通过Btree访问表里行记录的效率并不会随着相关表的数据量递增而显著下降,即通过走索引访问数据的时间是基本可控的,基本稳定的,这也是走索引和

全表扫描的最大区别。

索引的访问方式

1、索引唯一性扫描:针对唯一性索引的扫描,它仅仅适用于where条件里是等值查询目标的sql,因为扫描对象是唯一性索引,所以索引唯一性扫描的结果之多只会

返回一条记录

2、索引范围扫描:适用于所有类型的Btree索引

当对象是唯一性索引时,此事目标sql的where条件一定是范围查询

当扫描的对象是是非唯一性索引时,对目标sql的where条件没有限制

即使是针对同等条件下相同的sql,当目标索引的索引行数大于1时,索引范围扫描所耗费的逻辑读会多于索引唯一性所耗费的逻辑读。

这是因为索引唯一性扫描的搜啊秒结果至多只会返回一条记录,所以oracle明确知道此事只需要访问相关的叶子块一次就可以返回,但对于索引范围扫描而言,因为其

扫描结果可能返回多条数据,同事又因为目标索引的索引行数大于1,oracle为了去顶索引范围扫描的扫描终点,就不得不多次访问叶子块,所以同等条件下,目标索引的索引行数的数量大于1时,索引范围扫描所耗费的逻辑读至少比相应的唯一性扫描的逻辑读多1

3、索引全表扫描

适用于所有类型的Btree索引

所谓的索引全扫描就是指要扫描目标索引所有叶子块的所有索引行

要注意:索引全表扫描需要扫描目标索引所有叶子块,但这并不意味着需要扫描该索引的所有分支块,默认情况下,oracle在做索引全扫描的时候只需要通过访问必要的

分支块定位到位于该索引最左边的叶子块的第一行索引行,就可以利用该索引叶子块之间的双向指针链表,从左到右一次顺序扫描该索引所有叶子块的所有索引行。

索引全扫描的结果是有序的,并且是按照该索引的索引键值列来排序,这也意味着走索引全扫描既达到排序的效果,又同事避免了对该索引的索引键值列的真正排序操作。

索引全扫描的扫描结果的有序性就决定了索引全扫描是不能够并行执行的,并且通常情况下索引全扫描使用的是单块读。

通常情况下,索引全扫描是不需要回表的,所以索引全扫描适用于目标sql的查询列全部是目标索引的键值列的情况。

oralce中能做索引全扫描的前提条件是目标索引至少有一个索引键值列的属性是not null

4、索引快速全扫描:和快速全扫描纪委类似,也适用于所有类型的BTREE索引。

和索引全扫描的区别:

1、索引快速全扫描值适用于CBO

2、索引快速全扫描可以使用多块读,也可以并行执行

3、索引快速全扫描的执行结果不一定是有序的

5、索引跳跃式扫描:适用于所有类型的复核Btree索引,它使那些where条件中没有对目标索引的签到咧指定查询条件但同时又对该索引的非前导列指定查询条件但同时

又对该索引的非前导列指定了查询条件的目标sql依然可以用依然可以用上该索引,这就想是在扫描该索引时跳过了它的签到咧,直接从该索引的非签到咧开始查询一样。

Oracle中的索引跳跃式扫描仅仅适用于那些目标索引前导列的distinct值数量较少,后续非签到咧的可选择性有非常好的情况,因为索引跳跃式扫描的的执行效率一定会

随着目标索引签到咧的distinct值数量额递增而递减


表连接:表连接就是指多个表之间用条件连接在一起,使用表连接的目标sql的目的就是从多个表获取存储在这些表中的不同维度的数据

当优化器接下含有表连接的sql时,它除了会根据目标sql的sql文本的写法来决定表连接的类型之外,还必须确定如下三个步骤:

1、表连接的顺序 

2、表连接的方法

3、访问单表的方法

表连接的类型:

内连接:是指表连接的结果只包含那些完全满足连接条件的记录。

外连接:是对内连接的一种扩展,它是表连接结果除了包含那些完全满足连接条件的记录之外,还会包含驱动表中所有不满足该连接条件的记录。

oracle中使用的是自定义的(+)来表示外链接,其关键字(+)出现在哪个表的连接列后面,就表明哪个表会以null值来填充那些不满足连接条件位于

该表中的查询列,此事应该以关键字(+)对面的表来作为外链接的驱动表,这里的关键是决定那个表是驱动表


表连接的方法

排序合并连接,嵌套循环,哈希连接,笛卡尔连接四种

排序合并连接:是一种两个表在做连接时用排序操作和合并操作得到结果集的表连接方法

通常情况下,排序合并连接的执行效率不如哈希连接,但合并排序适用范围更广,因为哈希连接只能用于等值连接条件,而排序合并连接还能用于其他连接条件。

通常情况下,排序合并连接不适合OLTP类型的系统,其本质原因是因为对于oltp来兴的系统而言,排序是非常昂贵的操作,当然如果能避免排序操作,那么即使

OLTP类型的系统,也还是可以使用排序合并连接的。

嵌套循环连接:两个表在做连接的时候,依靠两层嵌套循环来得到连接结果集的表连接方法

嵌套循环的步骤

1)优化器按照一定的规则决定谁是驱动表,谁是被驱动表

2)接着以sql中的为此条件访问驱动表

3)从驱动表中得到的结果集遍历被驱动表

如果驱动表所对应的驱动结果集的记录数较少,同事在被驱动表的连接列上又存在唯一性索引,那么此时使用嵌套循环连接的执行效率就会非常高,但如果驱动

表所对应的驱动结果集的记录数很多,那么即便在被驱动表的连接上存在索引,此时使用嵌套循环连接的执行效率也不会高

只要驱动结果数量较少,那么就具备了做嵌套循环的前提矫健,而驱动结果集是在对驱动表应用了目标中指定的谓词条件后所到的结果集,所以大表也可以作为

嵌套循环的驱动表,关键看目标sql中指定的为此条件能否将驱动结果集的数量降下来

嵌套循环连接有其他连接方法所没有的一个优点:嵌套循环连接可以实现快读相应

如果oracle使用的是嵌套循环连接,且在被驱动表上存在索引,那么oracle在访问索引时通常会使用单块读,这意味着嵌套循环的驱动结果结有多少记录,oracle就

需要访问该索引多少次,如果目标SQL中的查询列并不能全部从连接的驱动结果集有多少条记录,那么oralce在昨晚嵌套循环连接完成后就需要对被驱动表执行回表

操作,这个回表的操作通常也是单块读,这就意味着做完嵌套循环后的连接结果集合有多少条记录,oralce就需要回标多少次。

为了提高嵌套循环连接的还行效率,oracle11g中引入了向量IO,在引入向量IO后,oracle就可以将原先一批单块读所需要耗费的物理IO组合起来,然后用一个向量

io去批量处理它们,这样就留实现了在单块读的数量不降低额情况下减少这些单块读所需要耗费的物理IO的次数,也就提高了嵌套循环的执行效率

哈希连接 :是一种两个表在做表连接的时候主要依靠哈希运算来得到连接结果集的表连接方法

oracle 7.3 中引入了哈希连接,从理论上说,哈希连接的效率会笔排序合并连接和嵌套循环连接要高,但这是不一定的。

oralce10g之后,优化器在解析目标sql时是否考虑到哈希连接是受限于隐含参数_HAS_JOIN_ENABLED,而在oralce10g以前,CBO在解析目标sql时是否考虑哈希

连接则首先与HASH_JOIN_ENABLE

_HASH_JOIN_ENABLED的默认值是TRUE,表示允许CBO在解析目标sql时考虑哈希连接,即使将该参数的值改成FALSE,使用USE_HASH Hint依然可以让CBO

在解析目标sql时候考虑哈希连接,这说明USE_HASH hint的优先级比2参数_HASH_JOIN_ENABLE高





0 0