背景:

按照《Oracle Conecpt》的结构一起了解Oracle数据库,这是学习Oracle从入门到精通的基础。




本文主题:第三章《Indexes and Index-Organized Tables》 - Overview of Indexes。


索引扫描

在索引扫描中,数据库会在语句中指定索引列值,遍历索引来提取数据。如果数据库扫描索引,他会消耗N次IO来得到需要的值,这里N是B树索引的高度。这就是Oracle数据库索引的基本原则。


如果一条SQL语句仅仅会访问索引列,那么数据库会直接从索引读取该值,不会从表中检索,即无需回表。如果语句需要访问除索引列外的其他列,则数据库会使用rowid定位表中的行。通常,数据库检索数据会读取一个索引块和一个表块。


可以参考:
《Oracle Database Performance Tuning Guide》了解关于索引扫描的详细信息。


全索引扫描

在全索引扫描中,数据库会按序读取整个索引。如果SQL中的谓词(WHERE子句)引用了索引中的一列,或者某些场景下未指定谓词,就会使用全索引扫描。由于全索引扫描中数据是按照索引键值排序的,因此这种扫描消除了排序。


假设应用运行下面的查询:

《Oracle Concept》第三章 - 5_Database

假设department_id,last_name和salary是复合索引键值。Oralce数据库会执行全索引扫描,按序(department_id和last_name)读取,并且使用salary字段作为过滤的条件。使用这种方法,数据库会扫描比employees表更小的数据集,因为所有检索列都包含在查询中了,避免了数据排序。


全扫描会读取整个索引,如下所示:

《Oracle Concept》第三章 - 5_键值_02


快速全索引扫描

快速全索引扫描是一种无需访问表的全索引扫描,数据库会无序地读取索引数据块。


快速全索引扫描是全表扫描的补充,他的执行需要满足以下条件:

  • 索引必须包含检索中的所有列。
  • 检索结果集中不会出现全空(null)的行。为了满足此要求,索引列至少满足以下条件之一:
    NOT NULL约束。
    在检索结果集中考虑谓词指定避免null空值。

例如,应用使用如下的检索语句,不包含ORDER BY子句中:

《Oracle Concept》第三章 - 5_键值_03


last_name列拥有NOT NULL约束。如果last_name和salary是复合索引键值,那么就会出现快速全索引扫描读取整个索引来获取请求的信息:

《Oracle Concept》第三章 - 5_数据库_04