Oracle数据库的可扩展索引、操作符与优化器
立即解锁
发布时间: 2025-08-24 02:13:32 阅读量: 1 订阅数: 4 

# Oracle 数据库的可扩展索引、操作符与优化器
## 1. 可扩展索引与操作符概述
传统数据库管理系统通常仅支持对部分数据类型(如数字和字符串)使用有限的访问方法(如 B+ 树和哈希索引)。然而,近年来数据库需要存储多种复杂数据类型,如文本、空间数据、图像、视频和音频等。对于简单数据类型,数据库系统能轻松处理索引的各个方面,但对于文档、图像、视频片段等复杂数据类型,由于其具有特定的应用格式、索引要求和选择谓词,传统的索引方法难以满足需求。
为了解决这一问题,Oracle 构建了可扩展服务器,允许应用开发者定义新的索引类型。其开发新索引类型的框架基于合作索引的概念,即数据插件和 Oracle 服务器协作,为包括文本、空间数据和在线分析处理(OLAP)等数据类型构建和维护索引。索引结构可以存储在 Oracle 数据库中(如堆表或索引组织表),也可以存储在外部(如操作系统文件),但为了便于并发控制和恢复,建议将域索引的物理存储放在 Oracle 数据库中。
### 1.1 Indextype 概念
Oracle8i 引入了 Indextype 的概念,其目的是为文本、空间数据、图像和 OLAP 等复杂领域提供高效的搜索和检索功能。Indextype 类似于 Oracle 服务器内置的排序或位图索引类型,不同之处在于实现 Indextype 的例程由插件开发者提供,而内置索引由 Oracle 服务器内核实现。一旦数据插件开发者实现了新的 Indextype,数据插件的最终用户就可以像使用内置索引类型一样使用它。
### 1.2 可扩展索引的功能
使用可扩展索引时,应用程序将域索引的结构定义为新的 Indextype,将索引数据存储在 Oracle 数据库内部(以表的形式)或外部,并管理、检索和使用索引数据来评估用户查询。当数据库服务器处理域索引的物理存储时,插件必须具备以下能力:
- **定义索引的格式和内容**:使插件能够定义适合复杂数据对象的索引结构。
- **构建、删除和更新域索引**:插件负责索引结构的构建和维护,这与为简单 SQL 数据类型提供的自动索引功能有很大不同。由于索引被建模为元组的集合,因此支持原地更新。
- **访问和解释索引的内容**:使数据插件成为查询处理的重要组成部分,即数据库查询中与内容相关的子句由数据插件处理。
### 1.3 ODCIIndex 接口功能
以下是 ODCIIndex 接口的功能列表:
| 接口例程 | 描述 |
| --- | --- |
| ODCIIndexCreate | 根据用户指定的参数创建域索引 |
| ODCIIndexDrop | 删除域索引 |
| ODCIIndexStart | 初始化域索引的扫描 |
| ODCIIndexFetch | 从域索引中获取满足操作符谓词的每一行的 rowid |
| ODCIIndexClose | 结束当前对索引的使用 |
| ODCIIndexInsert | 当索引表中插入一行时,维护域索引结构 |
| ODCIIndexDelete | 当索引表中删除一行时,维护域索引结构 |
| ODCIIndexUpdate | 当索引表中更新一行时,维护域索引结构 |
| ODCIIndexTruncate | 删除域索引数据,保留结构 |
| ODCIIndexAlter | 修改域索引 |
| ODCIIndexGetMetaData | 允许导入和导出特定于域索引的元数据 |
## 2. 相关索引和操作符类型
### 2.1 索引组织表(Index-Organized Tables)
索引组织表(IOT)是使用可扩展索引的插件开发者的有用工具。与普通表不同,IOT 的数据存储在其关联的索引中,表和索引实际上是一体的,更改表数据(如添加、更新或删除行)等同于更新索引。
IOT 类似于在一个或多个列上有索引的普通表,但数据库系统只维护一个 B* 树索引,该索引包含编码的键值和对应行的关联列值。数据行基于表的主键构建,每个 B* 树索引条目包含 <主键值, 非主键列值> 对。
IOT 适用于通过主键或任何有效的主键前缀访问数据,由于只存储非键列值与键一起,因此不会出现键值的重复。可以构建二级索引以提供对其他列的高效访问。
应用程序可以像操作普通表一样使用 SQL 语句操作 IOT,但数据库系统通过操作相应的 B* 树索引来执行所有操作。以下是普通表和索引组织表访问的主要区别:
| 普通表 | 索引组织表 |
| --- | --- |
| 基于 rowid 访问 | 基于主键访问 |
| ROWID 伪列中的物理 rowid 允许构建二级索引 | ROWID 伪列中的逻辑 rowid 允许构建二级索引 |
| rowid 唯一标识一行;主键可以可选指定 | 主键唯一标识一行;必须指定主键 |
| 顺序扫描返回所有行 | 全索引扫描按主键顺序返回所有行 |
| 允许 UNIQUE 约束和触发器 | 不允许 UNIQUE 约束;允许触发器 |
| 可以与其他表存储在集群中 | 不能存储在集群中 |
### 2.2 基于函数的索引(Function-Based Indexing)
数据插件开发者还可以基于行为进行索引。Oracle8i 支持基于函数的索引,以解决当谓词基于对象方法时查询的高效评估问题。用户可以在函数(对象方法)和涉及被索引表中一个或多个列的表达式上创建索引。基于函数的索引预先计算函数或表达式的值并将其存储在索引中,可以创建为 B* 树或位图索引。用于构建索引的函数必须是确定性的,即使用相同的参数值调用时必须返回相同的结果。
基于函数的索引为评估 WHERE 子句中包含函数的 SQL 语句提供了高效的机制。例如,可以创建一个基于函数的索引来物化计算密集型表达式,这样 Oracle 在处理 SELECT 或 DELETE 语句时无需计算表达式的值。但在处理 INSERT 和 UPDATE 语句时,Oracle 仍需评估函数以处理语句。
假设一个表包含所有采购订单对象,并且为采购订单类型定义了一个 TotalValue 方法,该方法通过汇总采购订单的各个行项目的值返回采购订单对象的总价值。可以创建如下索引:
```sql
CREATE INDEX TotalValueIndx ON purchase_order_table p
p.TotalValue();
```
当处理如下查询时,可以使用该索引而无需评估 TotalValue 方法:
```sql
SELECT p.order_id
FROM purchase_order_table p
WHERE p.TotalValue() > 10000;
```
### 2.3 用户定义的操作符(User-Defined Operators)
数据插件开发者可以定义特定于域的操作符,并将其集成到 Oracle8i 服务器中,同时利用可扩展索引方案来访问数据。通过添加这些特定于域的操作符来增加查询语言的语义,类似于扩展数据库的查询服务。
Oracle8i 提供了一组预定义的操作符,包括算术操作符(+、-、*、/)、比较操作符(=、>、<)和逻辑操作符(NOT、AND、OR)。用户可以通过定义具有用户指定行为的新操作符来扩展操作符集。新操作符像内置操作符一样,接受一组操作数作为输入并返回结果,其实现由用户提供。定义新操作符后,可以在 SQL 语句中像使用其他内置操作符一样使用它。
例如,如果用户定义了一个新的操作符 Contains,该操作符接受一个文本文档和一个查询字符串作为输入,如果文档满足指定的查询字符串则返回 TRUE,可以编写如下 SQL 查询:
```sql
SELECT *
FROM Employees
WHERE Contains(resume, ‘Oracle AND Unix’);
```
Oracle8i 使用索引来高效评估一些内置操作符,同样,在 Oracle8i 中,用户定义的域索引可以用于高效评估用户定义的操作符。一般来说,用户定义的操作符绑定到函数,但也可以使用索引进行评估。Indextype 为 Indextype 定义中列出的操作符提供基于索引的实现。
操作符绑定通过参数数据类型为操作符标识唯一的签名,并允许将提供操作符实现的函数与之关联。当操作符被调用时,Oracle8i 服务器执行该函数。只要签名不同,就可以定义多个操作符绑定。因此,任何操作符都可以有一组零个或多个关联的绑定,每个绑定都可以使用用户定义的函数进行评估,这些函数可以是独立函数、包函数或对象成员方法。用户定义的操作符可以在任何可以使用内置操作符的地方调用,即可以在表达式出现的任何地方使用。当操作符被调用时,其评估将转换为执行与之绑定的函数之一,这种转换基于操作符的参数数据类型。如果与操作符绑定的函数都不满足调用操作符时的签名,则会发生错误,转换过程中可能会进行一些隐式类型转换。
### 2.4 定义文本索引方案(Defining a Text-Indexing Scheme)
使用文本 Indextype 定义文本索引方案需要以下四个步骤:
1. **定义和编码支持操作符功能实现的函数**:假设文本索引方案旨在支持操作
0
0
复制全文
相关推荐









