第十一章(二)

二、执行路径总述

执行路径就是从数据库中查找数据的方式。
一般来说索引用于查询小的结果集,全表扫描在从表中得到很大结果集时高效一些。
对于oltp系统,包含许多运行时间较短、高选择性的语句,通常使用索引;而决策支持系统则更多地采用全表扫描。

1.全表扫描
高水位线下的所有数据块被扫描一遍,并过滤掉不符合条件的数据。
全表扫描时,块被顺序地读入读出。由于块是相邻的,每次i/o会比较大,相对于单个块的读取要快。读的大小从一个块大小到参数db_file_multblock_count指定的大小。

为什么全表扫描在得到大结果集时比较快?
全表扫描i/o调用大(can use larger I/O calls),执行少量的大I/O调用比执行较多的小I/O调用块。

什么时候使用全表扫描?
缺少索引  如:索引列上使用函数进行查询,不能使用索引,会走全表扫描。
数据量很大时  如果优化器认为查询需要获得表中绝大多数数据块,即使用索引,也会走全表扫描。
小表  如果高水位线下的数据块小于db_file_multiblock_read_count,那么一次i/o就可以完成读取,全表扫描笔用索引成本更低,就不管索引部分了。
并行度  高并行度将使优化器倾向于全表扫描。可以在all_tables中检查该表的degree列。

全表扫描的hint
通过full(表名)的hint,可以让执行计划走全表扫描,而不管是否有索引等。
通过nocache,可以让语句执行时不适用buffer cache中的数据;而cache则是将当前数据存到buffer cache中LRU的最近端。小表是默认cache的。中等规模的表缓存一部分数据,而大表不缓存。

并行查询
需要全表扫描时,数据库通过并行来提高效率。
并行查询一般用于低并发的数据仓库,由于潜在的资源使用。

2.ROWID SCANS
rowid指明了数据所在的数据文件、数据块以及块中行的位置。定位一行数据最快的方式就是通过rowid。
通过rowid进行查询,oracle首先获得所选行的rowid,从语句的where子句中或者通过一个或多个索引。
然后根据rowid定位每个选定的行

什么时候使用rowid扫描?
一般是根据索引找到rowid后的第二步。根据索引不能直接找到所有的行。

进行迁移、链接、导入导出等操作会是rowid发生变化,不推荐直接使用。

3.index scans
通过索引列的值找到数据。走索引路径时,语句直接从索引中取到数据。
索引中除了存储列值,还存储对应的rowid,如果需要其他列值,可通过rowid或cluster 查找找到数据所在位置,并提取。
(The index contains not only the indexed value, but also the rowids of rows in the table having that value. Therefore, if the statement accesses other columns in addition to the indexed columns, then Oracle Database can find the rows in the table by using either a table access by rowid or a cluster scan.)

(1)assesssing i/o for blocks,not rows
Oracle Database performs I/O by blocks. Therefore, the optimizer's decision to use full table scans is influenced by the percentage of blocks accessed, not rows. This is called the index clustering factor. If blocks contain single rows, then rows accessed and blocks accessed are the same.
However, most tables have multiple rows in each block. Consequently, the desired number of rows may be clustered in a few blocks or spread out over a larger number of blocks.
clustering factor指明了索引是适合程度。通常和表中相似的被索引值所在范围有关系。
clustering factor小,意味着表中单独行很少;而clustering factor值大,意味着表中相似值的位置比较分散。那么高clustering factor意味着根据rowid来查询需要更多花费,因为表中的很多块需要被访问。

(2)index unique scans
这种查询最多返回一个rowid。如果语句中包含了unique或主键约束,确保只有一行满足条件。

(3)index range scans
如果需要数据排序,使用order by子句而不依靠索引。如果一个索引能够满足order by的需要,优化器将使用这个选项,避免排序。

An index range scan is a common operation for accessing selective data. It can be bounded (bounded on both sides) or unbounded (on one or both sides). Data is returned in the ascending order of index columns. Multiple rows with identical values are sorted in ascending order by rowid.(对于高选择性的查询才有效)

在下列条件下有可能使用index range scans:
大于、小于、等于、and连接的索引列、like ‘X%’(即开头已知的like条件)
range scans既可以使用唯一索引,也可以是普通索引。

(4)index range scans descending
索引递减扫描是一种index range scan,除了数据递减排序。
索引默认是升序排列的。
当索引满足了order by descending条件时,使用这种索引。

(5)index skip scans
通过去除前导列来提高了索引检索的效率。
跳跃索引将混合索引分成了子索引。
跳跃索引中,混合索引的初始列在查询中不是明确的,换句话说,是跳跃的。
数据库通过初始列上的distinct值来决定逻辑子索引。
当混合索引的前导列上distinct值比较少、而非前导列上distinct值很多时适合使用跳跃索引。

数据库在混合索引前导列在查询谓词中不明确时可能选择跳跃索引。

例如性别列和邮箱列有一个索引,性别是前导列。如果只查询邮箱,数据库也可能使用跳跃索引,将性别列加上。

(6)full scans
索引全扫描,避免了排序操作,由于数据是按索引值排列的。用于以下情况:
1)
查询中的order by子句满足如下要求:
order by中所有列都有索引;
order by子句中列的顺序符合索引前导列的顺序;
order by子句能够包含所有索引或者子索引的列
2)
查询需要连接排序(sort merge join)。当查询满足下列条件时,快速索引扫描笔全表扫描高效:
查询中涉及的所有列都在索引上
查询中需要的列顺序与前导列的顺序相同
查询包含了索引中的全部列或者子集。
3)
在查询中group by子句列上有索引,数据行不需要在索引的相同顺序或group by的顺序。group by子句包含了索引的全部或部分列。

(7)fast full index scans
快速索引全扫描是全表扫描的一种,当索引包含了查询所需要的所有列,至少有一个索引上有为空约束。
在索引上进行快速全扫描,而不访问表。
通过这种方式无法对结果排序,因为数据并不是按索引键排列的。数据库需要对索引进行多块读(multiblock reads),并行的。

可以通过optimizer_features_enable参数或index_ffs这个hint来执行索引快速全扫描。这比普通的快速索引扫描要快,因为可以使用多块读,能够并行查询一张表。

(8)index joins
index join是包含了查询中所有数据列的一系列索引的hash join。
hint的方式:index_join

(9)bitmap index
Bitmap indexes and bitmap join indexes are available only in the Oracle Enterprise Edition.

4.cluster access
The database uses a cluster scan to retrieve all rows that have the same cluster key value from a table stored in an indexed cluster.
将存储在索引簇上的表中有相同簇值的数据查询出来。
索引簇上,数据库将相同数据块上的所有数据存储为相同的簇值。
进行cluster scna,数据库首先通过查询索引簇来获得某行的rowid,然后通过rowid定位该行数据。

5.hash access
使用hash scan,根据hash值,在hash cluster上定位行。
在hash cluster上,所有具有相同hash值的行被存储在相同数据库爱上。
进行hash scan,数据库先对语句中指定的一个簇值使用hash函数获得hash值,然后查询具有此hash值的数据行。

6.sample table scans
从一张表或复杂的查询语句中获得一条结果数据,
使用sample block clause对数据块进行采样输出,数据库读出特定比例的数据块。
如:select * from employees sample block(1);
只显示1%的数据。

7.查询优化器是如何选择路径的
根据以下两个条件:
语句的可选执行路径
使用每个路径或者路径组合的成本

查询优化器在选择路径时受两个条件影响:
优化器的hint:除了带有sample或sample block的语句外,可以通过hint来执行路径;
统计信息:如果一个表在创建后还没有收集过统计信息 ,并且在高水位线下有少于db_file_multblock_read_count的块,那么优化器认为这个表比较小,使用全表扫描。
通过all_tables表中last_analyzed和blocks列来检查统计信息。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26451536/viewspace-751237/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26451536/viewspace-751237/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值