Oracle 在选择执行计划的时候,优化器要决定用什么方法去访问存储在数据文件中的数据。我们从数据文件中查询到相关记录,有两种方法可以实现:1.直接访问表记录所在位置。2.访问索引,拿到索引中对应的rowid,然后根据rowid 去表中获取相应的数据。(有些情况,不需要再去表中取数据就可以得到相应的结果,那么就会直接返回)。

访问表的方法

  全表扫描

  全表扫描,Oracle 在取数据库数据的时候,从该表在硬盘上的第一个数据块开始,扫描到该表的最高水位线所在的数据块。在读的时候,会使用多块读的技术,将全表扫描一遍表数据,然后将不满足的数据剔除掉,返回需要的数据。Oracle 全表扫描的速度取决于最高水位线的大小。当表中的高水位线越大,需要消耗的资源(主要是I/O资源)越多。这样一来,耗费的时间也会增加。

  高水位:在Oracle中,表是属于表空间的,如果建表的时候,没有设置表空间,那么就会将当前用户的默认空间作为表格所在的表空间。如果一直往表中插入数据,分配给表的空间用完了,高水位线就会向上移动。如果用delete语句删除数据,水位线也不回降下来。这就会导致,有的表虽然只有几条数据,但是全表扫描就会很消耗性能。所以在进行大量的delete操作的时候,需要执行降水位的操作。

  ROWID 扫描

  rowId 类似于指针的概念。rowid和数据块中的行数据是一一对应的。我们知道某一行对应的rowid后,可以直接通过rowid去直接访问相应数据对应的数据行。Oracle 使用row取数据有两种:1、直接用rowId从取得相应数据。2、根据索引获得rowId,然后取数据。

  我们获取rowid的方法很简单,在每行记录中,都有一个Oracle内置的伪列rowId 直接在查询的时候去获取就可以了(注:这里需要将rowId 进行重命名,不然无法返回,不知道是不是笔者个人原因还是都需要这么写)。以emp表为例:

   SELECT ENAME ,EMPNO, rowId dataRowId FROM EMP;

  查出来的结果如下:

SMITH    7368    AAAtkkAAGAABqYkAAA
SMITH    7369    AAAtkkAAGAABqYkAAB
ALLEN    7499    AAAtkkAAGAABqYkAAC
WARD    7521    AAAtkkAAGAABqYkAAD
JONES    7566    AAAtkkAAGAABqYkAAE
MARTIN    7654    AAAtkkAAGAABqYkAAF
BLAKE    7698    AAAtkkAAGAABqYkAAG
CLARK    7782    AAAtkkAAGAABqYkAAH
SCOTT    7788    AAAtkkAAGAABqYkAAI
KING    7839    AAAtkkAAGAABqYkAAJ
TURNER    7844    AAAtkkAAGAABqYkAAK
ADAMS    7876    AAAtkkAAGAABqYkAAL
JAMES    7900    AAAtkkAAGAABqYkAAM
FORD    7902    AAAtkkAAGAABqYkAAN
MILLER    7934    AAAtkkAAGAABqYkAAO

  这里查出的rowId可以直接作为where条件去进行查询,SQL如下:

  SELECT ENAME ,EMPNO, rowId dataRowId FROM EMP where  rowId='AAAtkkAAGAABqYkAAA';

  执行结果:

  

  这条SQL的执行计划如下:

Plan hash value: 1116584662-----------------------------------------------------------------------------------
| Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |      |     1 |    22 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY USER ROWID| EMP  |     1 |    22 |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Note
-----

  从Id为1的这一行可以看出,执行计划走的是 BY USER ROWID 这个执行计划。我们对比下通过主键EMPNO去查询得到的执行计划:

  执行SQL如下:

 SELECT ENAME ,EMPNO, rowId dataRowId FROM EMP where  EMPNO='7368';

  执行结果跟通过rowId执行得到的执行结果一致:

  

  其执行计划如下:

Plan hash value: 2137789089---------------------------------------------------------------------------------------------
| Id  | Operation                         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |         |  8168 | 16336 |    29   (0)| 00:00:01 |
|   1 |  COLLECTION ITERATOR PICKLER FETCH| DISPLAY |  8168 | 16336 |    29   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

Note
-----

  可以看出,通过rowId得到的结果比使用主键进行查找的消耗要小的多,因为主键是先通过主键索引找到rowId,然后进行数据的提取操作,而rowId则是直接从数据文件中提取数据。

访问索引的方法

  索引结构(B树索引)

  在说通过索引扫描数据之前,先介绍下什么是索引。Oracle数据库中用的最多的是B树索引。B树索引的结构如下图所示:

  

  索引包含两个部分,一部分是索引分支块,另外一部分是叶子块。在数据根据索引进行扫描的时候,可以根据数据的内容,计算得出一个索引的值。然后根据索引值,得到响应的rowId,然后根据rowid,去数据文件取出相应的数据。Oracle 通过索引访问表里的记录的效率并不会随着相关表的数据量的递增而显著降低,所以索引访问数据的时间是基本稳定可控的。

  索引唯一性扫描(INDEX UNIQUE SCAN)

  索引唯一性扫描,是针对唯一性索引(unique scan)进行的扫描。当它的where条件是等于号的时候,扫描结果至多会返回一条数据记录。例如:sql语句:

select * from emp where EMPNO = 7368

  执行计划:

Plan hash value: 2949544139--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    37 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    37 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------2 - access("EMPNO"=7368)Note

  索引范围扫描(INDEX RANGE SCAN)

  范围索引扫描,使用于所有类型的B树索引,当扫描对象是唯一性索引时,目标的SQL条件一定是范围条件,例如 where 条件为between、<、> 等。

  例如,SQL语句为:

select * from emp where EMPNO > 7933

  执行计划为:

Plan hash value: 2787773736----------------------------------------------------------------------------------------------
| Id  | Operation                           | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |        |     1 |    37 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| EMP    |     1 |    37 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | PK_EMP |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------2 - access("EMPNO">7933)Note

  通过对比范围索引和唯一索引可以看出,即使使用同样的索引,范围索引也比唯一索引消耗更多的CPU,因为范围索引至少要多一次逻辑读。

  索引全扫描(INDEX FULL SCAN)

  索引在做全扫描的时候,要求索引不能为空。不然会漏掉null 的字段。索引全扫描在默认情况下,直接从第一个叶子节点,通过叶子节点之间相互的链表指针进行跳转。既能保证数据有序,又避免了对索引真正值的排序操作。

  sql语句:

SELECT EMPNO FROM EMP

  执行计划 :

Plan hash value: 179099197---------------------------------------------------------------------------
| Id  | Operation        | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |        |    16 |    64 |     1   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN | PK_EMP |    16 |    64 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------

Note

  索引快速全扫描(INDEX FAST FULL SCAN)

  索引快速扫描和索引全扫描类似,与之相比有如下区别:

  1.快速全扫描只适用于CBO。

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

  3.索引快速全扫描结果不一定有序。

  索引跳跃式扫描(INDEX SKIP SCAN)

  索引跳跃式扫描适用于组合索引。适用场景举例:当前索引有两个列,为:C1,C2。当我们的SQL语句where条件中,没有对C1进行筛选,而是对C2进行了筛选。那么有时候就会出现使用跳跃式索引扫描的情况。Oracle 中索引跳跃扫描适用于前导列可选择性较差,后续列的可选择性又非常好的场景。因为前导列包含的distinct值越少,跳跃次数也就越少,索引效率也就越高。

转载于:https://www.cnblogs.com/liyasong/p/oracle_index.html

Oracle 优化器_访问数据的方法_单表相关推荐

  1. Oracle 优化器_表连接

    概述 在写SQL的时候,有时候涉及到的不仅只有一个表,这个时候,就需要表连接了.Oracle优化器处理SQL语句时,根据SQL语句,确定表的连接顺序(谁是驱动表,谁是被驱动表及 哪个表先和哪个表做链接 ...

  2. oracle stalestats_深入理解oracle优化器统计数据(Optimizer Statistics)

    理解oracle优化器统计数据 首先来介绍oracle数据库使用基于规则优化器(RBO)来决定如何执行一个sql语句.基于规则优化器顾名思义,它是遵循一组规则来判断一个sql语句的执行计划.这组规则是 ...

  3. Oracle索引梳理系列(一)- Oracle访问数据的方法

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  4. Oracle 优化器

    什么是优化器 优化器是Oracle中的一个核心模块,它的作用是为用户输入的SQL选择一个它计算出来的最高效的执行计划.SQL语句在Oracle中的执行过程如下图所示: 基于规则优化器RBO 基于规则的 ...

  5. Oracle优化器:星型转换(Star Query Transformation )

     Oracle优化器:星型转换(Star Query Transformation )  Star query是一个事实表(fact table)和一些维度表(dimension)的join.每个维度 ...

  6. oracle优化器统计信息相关

    优化器使用统计信息来生成每个sql语句最优的执行计划.准确的统计信息对于数据库的效率至关重要. dba和程序开发人员都应该了解一些统计信息相关知识,这可以使你更好的理解为什么会生成一个你看到的执行计划 ...

  7. mysql和oracle优化器_Oracle 优化器

    一.优化器基本知识 Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执行计划去执行.分析语句的执行计划的工作是由优化器(Optimizer)来完成的.不同的情况,一条SQL可能 ...

  8. Oracle优化器:星型转换

    Oracle 8i中引入了星型转换(star transformation)的优化器新特性以便更有效地处理星型查询.星型查询语句多用于基于星型模型设计的数据仓库应用中.星型模型的称谓源于该种模型以图形 ...

  9. Visual Basic.NET中访问数据的方法(zz)

    http://info.shangdu.com/new/2003-5-8/200358113624.htm        Visual Basic.NET是微软对Visual Basic语言进行的升级 ...

最新文章

  1. sql安装错误解决办法
  2. 利用SQL Server EXISTS结构
  3. python中文软件-Python编程软件下载
  4. OSPF:LSA Type-7 to Type-5 转发地址抑制(实验)
  5. html中after伪类原理,css伪类before跟after原理与使用(原)
  6. javascript ||用法
  7. 【学术相关】不喜欢做研究,到底要不要读博士?
  8. pb数据窗口显示图片_HTAP数据库系列 | 企业级数据仓库如何应对个性化营销?
  9. bzoj4919 [Lydsy1706月赛]大根堆
  10. 自动化测试框架:没有Surprise的原因
  11. odoo10参考系列--视图三(其他高级视图)
  12. linux 删除桌面环境变量,linux下export命令添加、删除环境变量(转载)
  13. php ming.dll文件下载,phpshao.dll文件下载
  14. Mirth Connect 源码用eclipse启动
  15. git 找回删除的文件
  16. iOS 播放器静音设置方法
  17. Github标星25K+超火的Android实战项目,2022BTAJ面试真题详解
  18. 一加9 Pro和小米11 Pro哪个好?做了超多功课最终选择了它
  19. 【直击DTCC】自然语言技术在文智趋势分析产品的应用
  20. MPU6050姿态解算1-DMP方式

热门文章

  1. 语音网关上AA的配置解析
  2. SpringBoot整合Freemarker+Mybatis
  3. springboot EnableAutoConfiguration
  4. Atitit Java OpenCV 捕获视频
  5. SIGPIPE导致cronttab和shell脚本等工作异常
  6. 使用data uri将图片内嵌到html中
  7. 基于Windows 2008 R2 Core的SQL Server 2008 R2 Cluster部署(Step by Step)
  8. 创建与SharePoint 2010风格一致的下拉菜单 (续) 整合Feature Custom Action框架
  9. 弹窗页面PHP代码不执行,PHP代码没有被执行,而是代码显示在页面上
  10. 从源码分析DEARGUI之交互添加和删除组件