`
lxy2330
  • 浏览: 465614 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ORACLE执行计划

阅读更多

1 ,什么是执行计划

所谓执行计划,顾名思义,就是对一个查询任务,做出一份怎样去完成任务的详细方案。举个生活中的例子,我从珠海要去英国,我可以

选择先去香港然后转机,也可以先去北京转机,或者去广州也可以。但是到底怎样去英国划算,也就是我的费用最少,这是一件值得考究

的事情。同样对于查询而言,我们提交的SQL 仅仅是描述出了我们的目的地是英国,但至于怎么去,通常我们的SQL 中是没有给出提示信息

的,是由数据库来决定的。

  我们先简单的看一个执行计划的对比:

  SQL> set autotrace traceonly

  执行计划一:

  SQL> select count(*) from t;
  COUNT(*)
  ----------
  24815
  Execution Plan
  0    SELECT STATEMENT Optimizer=CHOOSE
  1   0   SORT (AGGREGATE)
  2   1    TABLE Access (FULL) OF 'T'

  执行计划二:

  SQL> select count(*) from t;
  COUNT(*)
  24815
  Execution Plan
  0    SELECT STATEMENT Optimizer=CHOOSE (Cost=26 Card=1)
  1   0   SORT (AGGREGATE)
  2   1    INDEX (FULL SCAN) OF 'T_INDEX' (NON-UNIQUE) (Cost=26 Card=28180)

  这两个执行计划中,第一个表示求和是通过进行全表扫描来做的,把整个表中数据读入内存来逐条累加; 第二个表示根据表中索引,把

整个索引读进内存来逐条累加,而不用去读表中的数据。但是这两种方式到底哪种快呢? 通常来说可能二比一快,但也不是绝对的。这是一

个很简单的例子演示执行计划的差异。对于复杂的SQL( 表连接、嵌套子查询等) ,执行计划可能几十种甚至上百种,但是到底那种最好呢?

我们事前并不知道,数据库本身也不知道,但是数据库会根据一定的规则或者统计信息(statistics) 去选择一个执行计划,通常来说选择的是

比较优的,但也有选择失误的时候,这就是这次讨论的价值所在。
 
Oracle
优化器模式

  Oracle 优化器有两大类,基于规则的和基于代价的,在SQLPLUS 中我们可以查看init 文件中定义的缺省的优化器模式。

  SQL> show parameters optimizer_mode
  NAME                  TYPE   VALUE
  optimizer_mode            string   CHOOSE
  SQL>

  这是Oracle8.1.7 企业版,我们可以看出,默认安装后数据库优化器模式为CHOOSE, 我们还可以设置为 RULE

FIRST_ROWS,ALL_ROWS 。可以在init 文件中对整个instance 的所有会话设置,也可以单独对某个会话设置:

  SQL> ALTER SESSION SET optimizer_mode  = RULE;
  会话已更改。
  SQL>  ALTER SESSION SET optimizer_mode  = FIRST_ROWS;
  会话已更改。
  SQL>  ALTER SESSION SET optimizer_mode  = ALL_ROWS;
  会话已更改。

  基于规则的查询,数据库根据表和索引等定义信息,按照一定的规则来产生执行计划; 基于代价的查询,数据库根据搜集的表和索引的

数据的统计信息( 通过analyze 命令或者使用dbms_stats 包来搜集) 综合来决定选取一个数据库认为最优的执行计划( 实际上不一定最优)

RULE 是基于规则的,CHOOSE 表示如果查询的表存在搜集的统计信息则基于代价来执行(CHOOSE 模式下Oracle 采用的是 FIRST_ROWS)

,否则基于规则来执行。在基于代价的两种方式中,FIRST_ROWS 指执行计划采用最少资源尽快的返回部分结果给客户端,对于排序分页

页显示这种查询尤其适用,ALL_ROWS 指以总体消耗资源最少的方式返回结果给客户端。

  基于规则的模式下,数据库的执行计划通常比较稳定。但在基于代价的模式下,我们才有更大的机会选择最优的执行计划。也由于

Oracle 的很多查询方面的特性必须在基于代价的模式下才能体现出来,所以我们通常不选择RULE( 并且Oracle 宣称从 Oracle 10i 版本数据库

开始将不再支持 RULE) 。既然是基于代价的模式,也就是说执行计划的选择是根据表、索引等定义和数据的统计信息来决定的,这个统计

信息是根据 analyze 命令或者dbms_stats 包来定期搜集的。首先存在着一种可能,就是由于搜集信息是一个很消耗资源和时间的动作,尤

其当表数据量很大的时候,因为搜集信息是对整个表数据进行重新的完全统计,所以这是我们必须慎重考虑的问题。我们只能在服务器空

闲的时候定期的进行信息搜集。这说明我们在一段时期内,统计信息可能和数据库本身的数据并不吻合; 另外就是Oracle 的统计数据本身也

存在着不精确部分( 详细参考Oracle DOCUMENT) ,更重要的一个问题就是及时统计数据相对已经比较准确,但是Oracle 的优化器的选择也

并不是始终是最优的方案。这也倚赖于Oracle 对不同执行计划的代价的计算规则( 我们通常是无法知道具体的计算规则的) 。这好比我们决定

从香港还是从北京去英国,车票、机票等实际价格到底是怎么核算出来的我们并不知道,或者说我们现在了解的价格信息,在我们乘车前

往的时候,真实价格跟我们的预算已经发生了变化。所有的因素,都将影响我们的整个开销。

  执行计划稳定性能带给我们什么

  Oracle 存在着执行计划选择失误的可能。这也是我们经常遇见的一些现象,比如总有人说我的程序在测试数据库中跑的很好,但在产

品数据库上就是跑的很差,甚至后者硬件条件比前者还好,这到底是为什么? 硬件资源、统计信息、参数设置都可能对执行计划产生影响。

由于因素太多,我们总是对未来怀着一种莫名的恐惧,我的产品数据库上线后到底跑的好不好? 于是Oracle 提供了一种稳定执行计划的能力

,也就是把在测试环境中的运行良好的执行计划所产生的OUTLINES 移植到产品数据库,使得执行计划不会随着其他因素的变化而变化。

  那么OUTLINES 是什么呢? 先要介绍一个内容,Oracle 提供了在SQL 中使用HINTS 来引导优化器产生我们想要的执行计划的能力。这在

多表连接、复杂查询中特别有效。HINTS 的类型很多,可以设置优化器目标(RULECHOOSEFIRST_ROWSALL_ROWS) ,可以指定表

连接的顺序,可以指定使用哪个表的哪个索引等等,可以对SQL 进行很多精细的控制。通过这种方式产生我们想要的执行计划的这些

HINTS,Oracle 可以存储这些HINTS ,我们称之为OUTLINES 。通过STORE OUTLINES 可以使得我们拥有以后产生相同执行计划的能力,也

就是使我们拥有了稳定执行计划的能力。

  这里想给出一个附加的说明就是,实际上,我们通过工具改写SQL ,比如使用SQL  EXPERT 改写后的SQL ,这些不仅仅是加了HINTS

而且文本都已经发生了变化的SQL ,也可以存储OUTLINES ,并可被应用到应用中。但这不是一定生效,我们必须测试检查是否生效。但由

于就算给了错误的OUTLINES, 数据库在执行的时候,也只是忽略过去重新生成执行计划而不会返回错误,所以我们才敢放心的这么使用。

当然在Oracle 文档中并没有指明可以这样做,文档中只是说明,如果存在OUTLINES 的同时又在SQL 中加了HINTS ,则会使用OUTLINES

忽略HINTS 。这个功能在LECCO 将发布的产品中会使用这一功能,这样可以将SQL EXPERT 的改写SQL 的能力和稳定执行计划的能力结合起

来,那么我们就对不能更改源代码的应用具有了相当强大的SQL 优化能力。

  也许我们会有疑问,假如稳定了执行计划,那还搜集统计信息干吗? 这是因为几个原因造成的,首先,现在的执行计划对于未来发生了

变化的数据未必就是合适的,存在着当前的执行计划不满足未来数据的变化后的效率,而新的统计信息的情况下所产生的执行计划也并不

是全部都合理的。那这个时候,我们可以采用新搜集的统计信息,但是却对新统计信息下不良的执行计划采用Oracle 提供的执行计划稳定

性这个能力固定执行计划,这样结合起来我们可以建立满意的高效的数据库运行环境。

  我们还需要关注的一个东西,Oracle 提供的dbms_stats 包除了具有搜集统计信息的能力,还具有把数据库中统计信息(statistics)

export/import 的能力,还具有只搜集统计信息而使得统计信息不应用于数据库的能力( 把统计信息搜集到一个特定的表中而不是立即生效)

,在这个基础上我们就可以把统计信息export 出来再import 到一个测试环境中,再运行我们的应用,在测试环境中我们观察最新的统计信

息会导致哪些执行计划发生变化(DB EXPERTPlan Version Tracer 是模拟不同环境并自动检查不同环境中执行计划变化的工具) ,是变好了

还是变差了。我们可以把变差的这一部分在测试环境中使用hints 或者利用工具(SQL EXPERT 是在重写SQL 这一领域目前最强有力的工具)

生良好的执行计划的SQL ,利用这些SQL 可以产生OUTLINES, 然后在产品数据库应用最新的统计信息的同时移植进这些OUTLINES

  最后说一下我们不得不使用执行计划稳定性能力的场合。我们假定Oracle 的优化器的选择都是准确的,但是优化器选择的基础就是我

们的SQL, 这些SQL 才从根本上决定了运行效率,这是更重要的一个优化的环节。SQL 是基础( 当然数据库的设计是基础的基础) ,一个SQL

的好不好,就相当于我们同样是要想去英国,但是我的起点在珠海,你的起点却在西藏的最边缘偏僻的一个地方,那不管你做怎样的最优

路线选择,你都不如我在珠海去英国所花费的代价小。

2 ,怎么生成的

1.Explain plan
explain plan for
select * from aa;
查看结果:
select * from table(dbms_xplan.display());
2.Autotrace Set timing on --
记录所用时间
Set autot trace --
自动记录执行计划
3.SQL_TRACE
ORACLE SQL_TRACE

“SQL TRACE” Oracle 提供的用于进行SQL 跟踪的手段,是强有力的辅助诊断工具。在日常的数据库问题诊断和解决中,“SQL TRACE”

非常常用的方法。

一般,一次跟踪可以分为以下几步:

1 、界定需要跟踪的目标范围,并使用适当的命令启用所需跟踪。


2
、经过一段时间后,停止跟踪。此时应该产生了一个跟踪结果文件。


3
、找到跟踪文件,并对其进行格式化,然后阅读或分析。


本文就“SQL TRACE” 的这些使用作简单探讨,并通过具体案例对SQL_TRACE 的使用进行说明。

3 ,怎么查看执行计划

Oracle10g 开始,可以通过EXPLAIN PLAN FOR 查看DDL 语句的执行计划了。

 

 

9i 及以前版本,Oracle 只能看到DML 的执行计划,不过从10g 开始,通过EXPLAIN PLAN FOR 的方式,已经可以看到DDL 语句的执行计划

了。

这对于研究CREATE TABLE AS SELECTCREATE MATERIALIZED VIEW AS SELECT 以及CREATE INDEXALTER INDEX REBUILD 等语

句有很大的帮助。

举个简单的例子,Oracle 的文档上对于索引的建立有如下描述:

The optimizer can use an existing index to build another index. This results in a much faster index build.

如果看不到DDL 的执行计划,只能根据执行时间的长短去猜测Oracle 的具体执行计划,但是这种方法没有足够的说服力。但是通过DDL 的执

行计划,就使得结果一目了然了。

SQL> CREATE TABLE T AS SELECT * FROM DBA_OBJECTS;

表已创建。

SQL> EXPLAIN PLAN FOR
2 CREATE INDEX IND_T_NAME ON T(OBJECT_NAME);

已解释。

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------
Plan hash value: 3035241083

-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | CREATE INDEX STATEMENT | | 57915 | 3732K| 75 (2)| 00:00:01 |
| 1 | INDEX BUILD NON UNIQUE| IND_T_NAME | | | | |
| 2 | SORT CREATE INDEX | | 57915 | 3732K| | |
| 3 | TABLE ACCESS FULL | T | 57915 | 3732K| 41 (3)| 00:00:01 |
-------------------------------------------------------------------------------------

Note
-----
- estimated index size: 5242K bytes

已选择14 行。

SQL> CREATE INDEX IND_T_OWNER_NAME ON T(OWNER, OBJECT_NAME);

索引已创建。

SQL> EXPLAIN PLAN FOR
2 CREATE INDEX IND_T_NAME ON T(OBJECT_NAME);

已解释。

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------
Plan hash value: 517242163

-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | CREATE INDEX STATEMENT | | 57915 | 3732K| 75 (2)| 00:00:01 |
| 1 | INDEX BUILD NON UNIQUE| IND_T_NAME | | | | |
| 2 | SORT CREATE INDEX | | 57915 | 3732K| | |
| 3 | INDEX FAST FULL SCAN| IND_T_OWNER_NAME | | | | |
-------------------------------------------------------------------------------------------

Note
-----
- estimated index size: 5242K bytes

已选择14 行。

SQL> SET AUTOT ON
SQL> CREATE INDEX IND_T_NAME ON T(OBJECT_NAME);

索引已创建。

注意,查看DDL 的执行计划需要使用EXPLAIN PLAN FORAUTOTRACE 对于DDL 是无效的。


4
,如何读懂执行计划:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'USER_INFO'
3 2 NESTED LOOPS
4 3 TABLE ACCESS (FULL) OF 'USER_NUM_TABLE'
5 3 INDEX (RANGE SCAN) OF 'PK_USER_INFO' (UNIQUE)
请问以上执行计划语句是如何看的?语句的执行顺序是什么?
让我们来解释一下怎么看吧, 左边的两列数字,第一列表示这条计划的编号,第二列是这条计划的父计划的编号;如果一条计划有子计划,

那么先要执行其子计划; 在这个例子中:从第一条编号为0 的(SELECT STATEMENT ptimizer=CHOOSE )开始,他有个子计划1SORT

(AGGREGATE) ),然后1 有个子计划22 有子计划3 3 有子计划4543 的第一个子计划,所以先执行4TABLE ACCESS (FULL)

OF 'USER_NUM_TABLE' ),再执行5(INDEX (RANGE SCAN) OF 'PK_USER_INFO' (UNIQUE))45 执行完返回到其父计划3NESTED

LOOPS ),345 取到的rows 进行nested loops ,结果再返回到2 ,再到1 排序,再到0select.

 

Oracle 执行计划解释

一.相关的概念

     Rowid 的概念:rowid 是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的。对每个表都有一个rowid 的伪列,但是表中并不物理存储 ROWID 列的值。不过你可以像使用其它列那样使用它,但是不能删除改列,也不能对该列的值进行修改、插入。一旦一行数据插入数据库,则rowid 在该行的生命周期内是唯一的,即即使该行产生行迁移,行的rowid 也不会改变。

    Recursive SQL 概念:有时为了执行用户发出的一个sql 语句,Oracle 必须执行一些额外的语句,我们将这些额外的语句称之为''recursive calls''''recursive SQL statements''. 如当一个DDL 语句发出后,ORACLE 总是隐含的发出一些recursive SQL 语句,来修改数据字典信息,以便用户可以成功的执行该DDL 语句。当需要的数据字典信息没有在共享内存中时,经常会发生Recursive calls ,这些Recursive calls 会将数据字典信息从硬盘读入内存中。用户不比关心这些recursive SQL 语句的执行情况,在需要的时候,ORACLE 会自动的在内部执行这些语句。当然DML 语句与SELECT 都可能引起recursive SQL. 简单的说,我们可以将触发器视为recursive SQL.

    Row Source (行源):用在查询中,由上一操作返回的符合条件的行的集合,即可以是表的全部行数据的集合;也可以是表的部分行数据的集合;也可以为对上2row source 进行连接操作(如join 连接)后得到的行数据集合。

    Predicate (谓词):一个查询中的WHERE 限制条件

    Driving Table (驱动表):该表又称为外层表(OUTER TABLE )。这个概念用于嵌套与HASH 连接中。如果该row source 返回较多的行数据,则对所有的后续操作有负面影响。注意此处虽然翻译为驱动表,但实际上翻译为驱动行源(driving row source )更为确切。一般说来,是应用查询的限制条件后,返回较少行源的表作为驱动表,所以如果一个大表在WHERE 条件有有限制条件(如等值限 制),则该大表作为驱动表也是合适的,所以并不是只有较小的表可以作为驱动表,正确说法应该为应用查询的限制条件后,返回较少行源的表作为驱动表。在执行计划中,应该为靠上的那个row source ,后面会给出具体说明。在我们后面的描述中,一般将该表称为连接操作的row source 1.

    Probed Table (被探查表):该表又称为内层表(INNER TABLE )。在我们从驱动表中得到具体一行的数据后,在该表中寻找符合连接条件的行。所以该表应当为大表(实际上应该为返回较大row source 的表)且相应的列上应该有索引。在我们后面的描述中,一般将该表称为连接操作的row source 2.

    组合索引(concatenated index ):由多个列构成的索引,如create index idx_emp on empcol1 col2 col3 …… ),则我们称idx_emp 索引为组合索引。在组合索引中有一个重要的概念:引导列(leading column ),在上面的例子中,col1 列为引导列。当我们进行查询时可以使用“where col1 = ,也可以使用“where col1 = and col2 = ,这样的限制条件都会使用索引,但是“where col2 = 查询就不会使用该索引。所以限制条件中包含先导列时,该限制条件才会使用该组合索引。

    可选择性(selectivity ):比较一下列中唯一键的数量和表中的行数,就可以判断该列的可选择性。 如果该列的 唯一键的数量/ 表中的行数 的比值越接近1 ,则该列的可选择性越高,该列就越适合创建索引,同样索引的可选择性也越高。在可选择性高的列上进 行查询时,返回的数据就较少,比较适合使用索引查询。

 

 

 

 

二. oracle 访问数据的存取方法

    1 全表扫描( Full Table Scans FTS

    为实现全表扫描, Oracle 读取表中所有的行,并检查每一行是否满足语句的 WHERE 限制条件一个多块读 操作可以使一次 I/O 能读取多块数据块( db_block_multiblock_read_count 参数设定),而不是只读取一个数据块,这极大的减 少了 I/O 总次数,提高了系统的吞吐量,所以利用多块读的方法可以十分高效地实现全表扫描,而且只有在全表扫描的情况下才能使用多块读操作。在这种访问模 式下,每个数据块只被读一次。

    使用 FTS 的前提条件:在较大的表上不建议使用全表扫描,除非取出数据的比较多,超过总量的 5% —— 10% ,或你想使用并行查询功能时。

    使用全表扫描的例子:

    ~~~~~~~~~~~~~~~~~~~~~~~~ SQL> explain plan for select * from dual;

    Query Plan

    -----------------------------------------

    SELECT STATEMENT[CHOOSE] Cost=

    TABLE ACCESS FULL DUAL

    2 通过 ROWID 的表存取( Table Access by ROWID rowid lookup

    行的 ROWID 指出了该行所在的数据文件、数据块以及行在该块中的位置,所以通过 ROWID 来存取数据可以快速定位到目标数据上,是 Oracle 存取单行数据的最快方法。

    这种存取方法不会用到多块读操作,一次 I/O 只能读取一个数据块。我们会经常在执行计划中看到该存取方法,如通过索引查询数据。

    使用 ROWID 存取的方法: SQL> explain plan for select * from dept where rowid = ''AAAAyGAADAAAAATAAF''

    Query Plan

    ------------------------------------

    SELECT STATEMENT [CHOOSE] Cost=1

    TABLE ACCESS BY ROWID DEPT [ANALYZED]


    3
)索引扫描( Index Scan index lookup

    我们先通过 index 查找到数据对应的 rowid 值(对于非唯一索引可能返回多个 rowid 值),然后根据 rowid 直接从表中得到具体的数据,这 种查找方式称为索引扫描或索引查找( index lookup )。一个 rowid 唯一的表示一行数据,该行对应的数据块是通过一次 i/o 得到的,在此情况下该次 i/o 只会读取一个数据库块。

            在索引中,除了 存储 每个索引的值外,索引还存储具有此值的行对应的 ROWID 值。索引扫描可以由 2 步组成:( 1 扫描索引得到对应的 rowid 值。 2 通过找到的 rowid 从表中读出具体的数据。每步都是单独的一次 I/O ,但是对于索引,由于经常使用,绝大多数都已经 CACHE 到内存中,所以第 1 步的 I/O 经常是逻辑 I/O ,即数据可以从内存中得到。但是对于第 2 步来说,如果表比较大,则其数据不可能全在内存中,所以其 I/O 很有可能是物理 I/O ,这 是一个机械操作,相对逻辑 I/O 来说,是极其费时间的。所以如果多大表进行索引扫描,取出的数据如果大于总量的 5% —— 10% ,使用索引扫描会效率下降很多。如下列所示: SQL> explain plan for select empno ename from emp where empno=10

    Query Plan

    ------------------------------------

    SELECT STATEMENT [CHOOSE] Cost=1

    TABLE ACCESS BY ROWID EMP [ANALYZED]

    INDEX UNIQUE SCAN EMP_I1


   
但是如果查询的数据能全在索引中找到,就可以避免进行第 2 步操作,避免了不必要的 I/O ,此时即使通过索引扫描取出的数据比较多,效率还是很高的

    SQL> explain plan for select empno from emp where empno=10;-- 只查询 empno 列值

    Query Plan

    ------------------------------------

    SELECT STATEMENT [CHOOSE] Cost=1

    INDEX UNIQUE SCAN EMP_I1

    进一步讲,如果 sql 语句中对索引列进行排序,因为索引已经预先排序好了,所以在执行计划中不需要再对索引列进行排序
    SQL> explain plan for select empno, ename from emp

    where empno > 7876 order by empno;

    Query Plan

    --------------------------------------------------------------------------------

    SELECT STATEMENT[CHOOSE] Cost=1

    TABLE ACCESS BY ROWID EMP [ANALYZED]

    INDEX RANGE SCAN EMP_I1 [ANALYZED]


   
从这个例子中可以看到:因为索引是已经排序了的,所以将按照索引的顺序查询出符合条件的行,因此避免了进一步排序操作。

    根据索引的类型与where 限制条件的不同,有4 种类型的索引扫描:

    索引唯一扫描(index unique scan

    索引范围扫描(index range scan

    索引全扫描(index full scan

    索引快速扫描(index fast full scan

    1 ) 索引唯一扫描(index unique scan

    通过唯一索引查找一个数值经常返回单个ROWID. 如果存在UNIQUE PRIMARY KEY 约束(它保证了语句只存取单行)的话,Oracle 经常实现唯一性扫描。

    使用唯一性约束的例子:

    SQL> explain plan for

    select empno ename from emp where empno=10

    Query Plan

------------------------------------

    SELECT STATEMENT [CHOOSE] Cost=1

    TABLE ACCESS BY ROWID EMP [ANALYZED]

    INDEX UNIQUE SCAN EMP_I1

    2 ) 索引范围扫描(index range scan

    使用一个索引存取多行数据,在唯一索引上使用索引范围扫描的典型情况下是在谓词(where 限制条件)中使用了范围操作符(如><<>>=<=between

    使用索引范围扫描的例子:

    SQL> explain plan for select empno ename from emp

    where empno > 7876 order by empno

    Query Plan

--------------------------------------------------------------------------------

    SELECT STATEMENT[CHOOSE] Cost=1

    TABLE ACCESS BY ROWID EMP [ANALYZED]

    INDEX RANGE SCAN EMP_I1 [ANALYZED]

    在非唯一索引上,谓词col = 5 可能返回多行数据,所以在非唯一索引上都使用索引范围扫描。

    使用index rang scan3 种情况:

    a ) 在唯一索引列上使用了range 操作符(> < <> >= <= between

    b ) 在组合索引上,只使用部分列进行查询,导致查询出多行

    c ) 对非唯一索引列上进行的任何查询。

    3 ) 索引全扫描(index full scan

    与全表扫描对应,也有相应的全索引扫描。而且此时查询出的数据都必须从索引中可以直接得到。

    全索引扫描的例子:

    An Index full scan will not perform single block i/o''s and so it may prove to be inefficient.

    e.g.

    Index BE_IX is a concatenated index on big_emp empno ename

    SQL> explain plan for select empno ename from big_emp order by empnoename

    Query Plan

--------------------------------------------------------------------------------

    SELECT STATEMENT[CHOOSE] Cost=26

    INDEX FULL SCAN BE_IX [ANALYZED]

    4 ) 索引快速扫描(index fast full scan

    扫描索引中的所有的数据块,与 index full scan 很类似,但是一个显著的区别就是它不对查询出的数据进行排序,即数据不是以排序顺序被返回。在这种存取方法中,可以使用多块读功能,也可以使用并行读入,以便获得最大吞吐量与缩短执行时间。

    索引快速扫描的例子:

    BE_IX 索引是一个多列索引: big_emp empnoename

    SQL> explain plan for select empno ename from big_emp

    Query Plan

------------------------------------------

    SELECT STATEMENT[CHOOSE] Cost=1

    INDEX FAST FULL SCAN BE_IX [ANALYZED]

分享到:
评论

相关推荐

    oracle 执行计划 详解

    "Oracle 执行计划详解" Oracle 执行计划是数据库性能优化的关键。为了更好地理解和优化 Oracle 数据库的执行计划,我们需要了解执行计划的生成过程、优化方法和执行计划的解读方法。 执行计划生成过程 执行计划的...

    Oracle执行计划参数解释

    Oracle执行计划参数解释,Oracle SQL优化的基础是看懂Oracle的执行计划,本文当系统整理了Oracle执行计划里面的各种参数。

    oracle执行计划解读

    Oracle 执行计划解读 Oracle 执行计划是一种查询执行路径的表示形式,它展示了 Oracle 数据库在执行查询时访问数据的路径。下面是 Oracle 执行计划的详细解读,包括执行计划的定义、访问数据的方式、执行计划层次...

    oracle执行计划建立与阅读

    Oracle执行计划是数据库管理系统在处理SQL语句时的预估工作流程,它是Oracle优化器根据当前数据分布、索引情况和系统资源等信息选择的最佳执行策略。了解和分析执行计划对于提升SQL语句的性能至关重要。 一、生成...

    Oracle 执行计划PPT

    Oracle 执行计划是数据库管理系统在处理SQL查询时制定的一系列步骤,用于高效地检索和处理数据。它是Oracle数据库优化器(Optimizer)根据统计信息、成本估算和已存在的索引等信息生成的。优化器有两种主要的工作...

    oracle执行计划详解

    Oracle 执行计划详解是数据库管理系统中一个非常重要的概念。本文将详细介绍 Oracle 执行计划的相关概念、访问数据的存取方法、表之间的连接等内容,并对总结和概述,以便于理解和记忆。 一、相关的概念 1. Rowid ...

    oracle执行计划文档

    除了以上概念,Oracle执行计划还包括其他访问方法,如索引扫描(Index Scan)、索引唯一扫描(Index Unique Scan)、索引快速全扫描(Index Fast Full Scan)以及各种类型的连接操作,如嵌套循环(Nested Loop)、...

    ORACLE执行计划和SQL调优.pptx

    ORACLE 执行计划和 SQL 调优 ORACLE 执行计划和 SQL 调优是关系数据库管理系统中非常重要的概念。执行计划是 Oracle 优化器生成的,用于描述如何访问数据库中的数据的计划。execute plan 中包括了访问路径、表扫描...

    Oracle执行计划详解

    Oracle执行计划详解,包括oracle执行顺序和索引详细介绍

    ORACLE执行计划和SQL调优

    ORACLE执行计划和SQL调优

    oracle执行计划详细解释

    oracle执行计划详细解释

    Oracle执行计划.ppt

    Oracle 执行计划 Oracle 执行计划是 Oracle 数据库中的一种机制,用于确定如何访问存储器,得到需要的结果集。执行计划的主要内容包括访问方式和访问顺序。下面是 Oracle 执行计划的详细知识点: 一、执行计划的...

    Oracle 执行计划稳定性

    总之,Oracle执行计划的稳定性对于数据库的高效运行具有重要意义。通过合理管理统计信息、选择合适的优化器模式、利用SQL提示和监控工具,可以有效控制执行计划的稳定性,从而提升数据库的整体性能。

    Oracle执行计划1.ppt

    "Oracle 执行计划" Oracle 执行计划是 Oracle 数据库中的一种机制,用于优化 SQL 语句的执行过程。它决定了如何访问存储器,得到需要的结果集。执行计划的主要内容包括访问方式和访问顺序。 Oracle 执行计划的生成...

    Oracle 执行计划、表分区

    本文将深入探讨Oracle的执行计划和表分区两个重要概念,以及它们如何影响数据库性能。 执行计划是Oracle数据库处理SQL查询的一种步骤序列,它详细描述了数据如何从表中提取、如何进行排序或聚合,以及如何返回到...

Global site tag (gtag.js) - Google Analytics