官方文档链接地址 http://docs.oracle.com/cd/E11882_01/server.112/e40540/indexiot.htm#CNCPT1170

Index Scans

  • 在索引扫描中,数据库使用语句指定的索引列,通过遍历索引来检索行。数据库为一个值扫描索引时,发生 n 次 I/O 就能找到其要查找的值,其中 n 即 B-树索引的高度。这是数据库索引背后的基本原理
  • 如果 SQL 语句仅访问被索引的列,那么数据库只需直接从索引中读取值,而不用读取表。如果该语句同时还访问除索引列之外的列,那么数据库会使用 rowids 来查找表中的行。通常,为检索表数据,数据库以轮流方式先读取索引块,然后读取相应的表块

Full Index Scan

  • 在索引全扫描中,数据库有顺序地读取整个索引。如果在 SQL 语句中的谓词(WHERE 子句)引用了一个索引列,或某些未指定任何谓词的情况,此时可能使用索引全扫描。全扫描可以消除排序,因为数据本身就是基于索引键排过序的
  • 假设应用程序运行以下查询:
SELECT department_id, last_name, salary
FROM employees
WHERE salary > 5000
ORDER BY department_id, last_name;
  • 此外假定 department_id、last_name、salary 是一个复合索引键。Oracle 数据库会执行索引全扫描,按顺序(部门 ID 和姓氏顺序)读取并使用薪金进行筛选。通过这种方式,数据库只需扫描一个小于 employees 表的数据集,包含的列比查询中的列多,并避免了对数据进行排序
  • 例如:索引全扫描可能会这样读取索引条目
50,Atkinson,2800,rowid
60,Austin,4800,rowid
70,Baer,10000,rowid
80,Abel,11000,rowid
80,Ande,6400,rowid
110,Austin,7200,rowid
.
.
.

Fast Full Index Scan

  • 快速索引全扫描是一种索引全扫描,数据库仅访问索引本身中的数据,而无需访问表,数据库并不按特定的顺序读取索引块
  • 当下面的条件同时满足时,快速完全索引扫描可以替代全表扫描
  • 1)索引必须包含查询所需要的所有列
  • 2)查询结果集中不会出现全是 NULL 的行,要想保证这一点,至少有一个索引列列符合下面的条件之一:
  • NOT NULL 约束
  • 应用到该列的谓词阻止 NULL 值作为结果集
  • 例如,应用程序发出以下查询,不包含 ORDER BY 子句
SELECT last_name, salary
FROM employees;
  • last_name 上有非空约束,last_name 和 salary 是一个复合索引键,那么快速索引全扫描只需读取索引条目,就可以获得需要的信息
Baida,2900,rowid
Zlotkey,10500,rowid
Austin,7200,rowid
Baer,10000,rowid
Atkinson,2800,rowid
Austin,4800,rowid
.
.
.

Index Range Scan

  • 索引范围扫描是对索引的有序扫描,具有以下特点:
  • 在条件中指定了一或多个索引前导列。条件指定一或多个表达式与逻辑(布尔)运算符的组合,并返回一个值(TRUE/FALSE/UNKNOWN)
  • 一个索引键可能对应 0个、1个或多个值
  • 通常,数据库使用索引范围扫描来访问具有选择性的数据。选择性是查询所选择的行占总行数的百分比,0 意味着没有行,1 表示所有行。选择性与一个查询谓词相关,比如 WHERE last_name LIKE 'A%',或者与多个谓词有关。值越接近 0 的谓词越具有选择性,相反,越接近 1 的谓词则越不具有选择性
  • 例如,用户查询姓氏以 A开头的雇员。假定 last_name 列已被索引,其索引条目如下所示:
Abel,rowid
Ande,rowid
Atkinson,rowid
Austin,rowid
Austin,rowid
Baer,rowid
.
.
.
  • 数据库可以使用范围扫描,因为在谓词中指定了 last_name 列,而且每个索引键可能对应多个 rowids。例如有两个雇员名叫 Austin,所以有两个 rowids 都与索引键 Austin 相关联
  • 索引范围扫描可以在两边都有边界,比如部门 ID 在 10~40 之间的查询,或只在一边有界,比如部门 id > 40 的查询。为扫描索引,数据库将在叶块之间前后移动。例如,对于 ID 在 10~40 之间的扫描,将先定位到包含最低键值(大于或等于10)的第一个索引叶块。然后顺着各个被链接的叶节点水平推进,直到它找到一个大于 40 的值为止

Index Unique Scan

  • 相对于索引范围扫描,索引唯一扫描必须有 0或1 个 rowid 与索引键相关联。当一个谓词使用相等运算符引用了唯一索引键的所有列时,数据库将执行唯一扫描。只要找到了第一个记录,索引唯一扫描就停止处理,因为不可能有第二个记录满足条件
  • 假设用户运行以下查询:
SELECT *
FROM employees
WHERE employee_id = 5;
  • 假定 employee_id 是主键并具有以下的索引条目:
1,rowid
2,rowid
4,rowid
5,rowid
6,rowid
.
.
.
  • 在这种情况下,数据库使用索引唯一扫描来定位 ID 是5的雇员的 rowid

Index Skip Scan

  • 索引跳跃扫描使用复合索引的逻辑子索引。数据库 "跳跃地" 通过单个索引,就像它是在多个单独的索引中搜索一样。如果在复合索引前导键列中有少量不同值,而在非前导键列中有大量不同值,此时使用跳跃扫描是有益的
  • 当在查询谓词中未指定复合索引的前导列时,数据库可能选择索引跳跃扫描。例如,假定你要在 sh.customers 表中查找一个客户,运行如下查询:
SELECT * FROM sh.customers WHERE cust_email = 'Abbey@company.com';
  • customers 表中有一列 cust_gender,其值为 M 或F。假定在列 cust_gender 和 cust_email上存在一个复合索引。示例3-1 显示了索引条目的一部分
F,Wolf@company.com,rowid
F,Wolsey@company.com,rowid
F,Wood@company.com,rowid
F,Woodman@company.com,rowid
F,Yang@company.com,rowid
F,Zimmerman@company.com,rowid
M,Abbassi@company.com,rowid
M,Abbey@company.com,rowid
  • 即使没有在 WHERE 子句中指定 cust_gender 列,数据库可以使用跳跃索引扫描
  • 在跳跃扫描中,逻辑子索引的数目取决于前导列中的非重复值的数目。在示例 3-1 中,前导列中有两个可能值。数据库在逻辑上将该索引拆分为一个具有键 F 的子索引和另一个具有键 M 的子索引
  • 当搜索电子邮件为 Abbey@company.com 的客户的记录时, 数据库首先搜索值 F的子索引,然后搜索值 M 的子索引。从概念上讲,数据库按照下面的方式处理查询:
SELECT * FROM sh.customers WHERE cust_gender = 'F'
AND cust_email = 'Abbey@company.com'
UNION ALL
SELECT * FROM sh.customers WHERE cust_gender = 'M'
AND cust_email = 'Abbey@company.com';

Index Clustering Factor

  • 索引集群因子用于测量相对于某个索引值(如雇员姓氏)的行的有序度。被索引值的行存储的越有序,则集群因子越低

  • 作为一种粗略测量通过索引读取整个表所需的 I/O 数,集群因子非常有用

    • 如果集群因子较高,则在大索引范围扫描过程中,数据库将执行相对较高的 I/O。索引条目指向随机的表块,因此数据库可能必须一遍又一遍地来回读索引所指向的同一数据块
    • 如果集群因子较低,则在大索引范围扫描过程中数据库将执行相对较低的 I/O。在一个范围内的索引键倾向于指向同一个数据块,因此该数据库不需要来回读同一个数据块
  • 集群因子与索引扫描关系密切,因为它可以显示:

    • 数据库是否会在大范围扫描中使用索引
    • 表相对于索引键的组织度
    • 如果行必须按索引键排序,是否应考虑使用索引组织表、分区或表簇
  • 例如,假定雇员表存放在两个数据块中。表 3-1 描述了两个数据块中的行(省略号表示未显示的数据)

  • 行按姓氏(以粗体显示)顺序存储在块中。例如,数据块 1 的最下面一行描述了 Abel, 往上一行描述了 Ande,如此等等,按字母顺序直到最上面的一行描述了 Steven King。数据块 2 中的最下面行描述了 Kochar,往上一行描述了 Kumar ,如此等等,按字母顺序直到最后一行描述了 Zlotkey

  • 假设在姓氏列上存在一个索引。每个姓氏条目对应于一个 rowid。从概念上讲,索引条目看起来如下所示:

Abel,block1row1
Ande,block1row2
Atkinson,block1row3
Austin,block1row4
Baer,block1row5
.
.
.
  • 假设在雇员 ID 列上存在另一个单独的索引。从概念上讲,索引条目可能看起来像下面这样,雇员 id 几乎分布在这两个数据块的任意位置
100,block1row50
101,block2row1
102,block1row9
103,block2row19
104,block2row39
105,block1row4
.
.
.
  • 示例 3-2 所示的查询,通过 ALL_INDEXES 查看这两个索引的集群因子。EMP_NAME_IX 的集群因子较低,这意味着在同一个叶块中的相邻索引条目倾向于指向同一个数据块中的行。EMP_EMP_ID_PK 的集群因子较高,这意味着同一个叶块中的相邻索引条目不太可能指向同一个数据块中的行
SQL> SELECT INDEX_NAME, CLUSTERING_FACTOR
2 FROM ALL_INDEXES
3 WHERE INDEX_NAME IN ('EMP_NAME_IX','EMP_EMP_ID_PK');
INDEX_NAME CLUSTERING_FACTOR
-------------------- -----------------
EMP_EMP_ID_PK 19
EMP_NAME_IX 2

Index Scans 索引扫描的更多相关文章

  1. ORACLE Index Lookup索引访问路径总结

    在ORACLE中,索引访问/查找(Index Lookup)路径有五种方式,分别为INDEX UNIQUE SCAN.INDEX RANGE SCAN.INDEX FULL SCAN.INDEX FA ...

  2. SQL SERVER中什么情况会导致索引查找变成索引扫描

    SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Index Scan)呢? 下面从几个方面结合上下文具体场景做了下测试.总结.归纳. 1:隐式转换会导致 ...

  3. MySQL 优化之 index merge(索引合并)

    深入理解 index merge 是使用索引进行优化的重要基础之一.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 1. 为什么会有index merge 我们的 where ...

  4. Oracle 表的访问方式(2)-----索引扫描

    索引扫描(Index scan) 我们先通过index查找到数据对应的rowid值(对于非唯一索引可能返回多个rowid值),然后根据rowid直接从表中得到具体的数据,这种查找方式称为索引扫描或索引 ...

  5. 【翻译自mos文章】SYS_OP_C2C 导致的全表扫描(fts)/全索引扫描

    SYS_OP_C2C 导致的全表扫描(fts)/全索引扫描 參考原文: SYS_OP_C2C Causing Full Table/Index Scans (Doc ID 732666.1) 适用于: ...

  6. Oracle 索引扫描的五种类型

    之前在讨论CBO和RBO的时候提到了索引扫描的几种类型. Oracle Optimizer CBO RBO http://blog.csdn.net/tianlesoftware/archive/20 ...

  7. Sql Server 聚集索引扫描 Scan Direction的两种方式------FORWARD 和 BACKWARD

    最近发现一个分页查询存储过程中的的一个SQL语句,当聚集索引列的排序方式不同的时候,效率差别达到数十倍,让我感到非常吃惊 由此引发出来分页查询的情况下对大表做Clustered Scan的时候, 不同 ...

  8. SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析

    在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...

  9. Oracle索引梳理系列(八)- 索引扫描类型及分析(高效索引必备知识)

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

随机推荐

  1. PHP三维数组拼装

    foreach ($records as $k => $v) { foreach ($records as $m => $n) { if ($v['days'] == $n['days'] ...

  2. linux 下 查看是32位还是64位系统 命令

    文章引自:http://zhidao.baidu.com/question/583981849.html 方法1:getconf LONG_BIT 查看 如下例子所示: 32位Linux系统显示32, ...

  3. ScheduledFuture和RunnableScheduledFuture详解

      ScheduledFuture java.util.concurrent 接口 ScheduledFuture<V> 类型参数:     V - 此 Future 返回的结果类型. 所 ...

  4. 分布式缓存技术redis学习—— 深入理解Spring Redis的使用

    关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么 ...

  5. 使用函数指针调用C++虚函数

    基本概念: 1. 函数指针,一个地址指针变量,其值指向代码区的某个函数首地址. 2. 虚函数,可以被子类覆写的C++成员函数.由虚函数表实现. 3. 虚函数表指针(vpt),指向虚函数表首地址的指针, ...

  6. Linux环境g++编译GDAL动态库

    一.编译步骤 解压下载的GDAL源程序,并在命令行中切换到解压目录. tar -xzvf gdal-2.1.3.tar.gz cd gdal-2.1.3 GDAL可通过configure来实现一些自定 ...

  7. 如何使用华为软件开发云快速部署PHP网站

    华为软件开发云这个工具,从去年推出我就一直在关注,毕竟是华为最新的一款软件开发工具,最近我一直在使用华为软件开发云进行开发项目管理,它有在线编译和构建.云端在线代码检查等功能,编译省去了很多物理机器的 ...

  8. 开涛spring3(3.2) - DI之循环依赖

    3.2.1  什么是循环依赖 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用 CircleC,CircleC引用CircleA ...

  9. ionic 使用mobisscrolls,实现日期选择的插件

    废话不多说,直接说用法: 1,先下载mobisscrolls的破解版,下载地址,链接:http://pan.baidu.com/s/1boSKf51 密码:5dft 当然你也可以去官网下载,不过官网的 ...

  10. 【面向对象设计原则】之接口隔离原则(ISP)

    接口隔离原则(Interface  Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口. 从接口隔离原则的定义可以看 ...