** 25. ** ** 用索引提高效率 **
索引是表的一个概念部分 , 用来提高检索数据的效率 . 实际上 ,ORACLE 使用了一个复杂的自平衡 B-tree 结构 . 通常 , 通过索引查询数据比全表扫描要快 . 当 ORACLE 找出执行查询和 Update 语句的最佳路径时 , ORACLE 优化器将使用索引 . 同样在联结多个表时使用索引也可以提高效率 . 另一个使用索引的好处是 , 它提供了主键 (primary key) 的唯一性验证 .
除了那些 LONG 或 LONG RAW 数据类型 , 你可以索引几乎所有的列 . 通常 , 在大型表中使用索引特别有效 . 当然 , 你也会发现 , 在扫描小表时 , 使用索引同样能提高效率 .
虽然使用索引能得到查询效率的提高 , 但是我们也必须注意到它的代价 . 索引需要空间来
存储 , 也需要定期维护 , 每当有记录在表中增减或索引列被修改时 , 索引本身也会被修改 . 这意味着每条记录的 INSERT , DELETE , UPDATE 将为此多付出 4 , 5 次的磁盘 I/O . 因为索引需要额外的存储空间和处理 , 那些不必要的索引反而会使查询反应时间变慢 .
** 译者按 : **
** 定期的重构索引是有必要的 . **
** ALTER INDEX
1<indexname> REBUILD <tablespacename> **
2
3** 26\. ** ** 索引的操作 **
4
5ORACLE 对索引有两种访问模式 .
6
7索引唯一扫描 ( INDEX UNIQUE SCAN)
8
9大多数情况下 , 优化器通过 WHERE 子句访问 INDEX.
10
11例如 :
12
13表 LODGING 有两个索引 : 建立在 LODGING 列上的唯一性索引 LODGING_PK 和建立在 MANAGER 列上的非唯一性索引 LODGING$MANAGER.
14
15SELECT *
16
17FROM LODGING
18
19WHERE LODGING = ‘ROSE HILL’;
20
21在内部 , 上述 SQL 将被分成两步执行 , 首先 , LODGING_PK 索引将通过索引唯一扫描的方式被访问 , 获得相对应的 ROWID, 通过 ROWID 访问表的方式 执行下一步检索 .
22
23如果被检索返回的列包括在 INDEX 列中 ,ORACLE 将不执行第二步的处理 ( 通过 ROWID 访问表 ). 因为检索数据保存在索引中 , 单单访问索引就可以完全满足查询结果 .
24
25下面 SQL 只需要 INDEX UNIQUE SCAN 操作 .
26
27SELECT LODGING
28
29FROM LODGING
30
31WHERE LODGING = ‘ROSE HILL’;
32
33索引范围查询 (INDEX RANGE SCAN)
34
35适用于两种情况 :
36
371\. 基于一个范围的检索
38
392\. 基于非唯一性索引的检索
40
41例 1:
42
43SELECT LODGING
44
45FROM LODGING
46
47WHERE LODGING LIKE ‘M%’;
48
49WHERE 子句条件包括一系列值 , ORACLE 将通过索引范围查询的方式查询 LODGING_PK . 由于索引范围查询将返回一组值 , 它的效率就要比索引唯一扫描
50
51低一些 .
52
53例 2:
54
55SELECT LODGING
56
57FROM LODGING
58
59WHERE MANAGER = ‘BILL GATES’;
60
61这个 SQL 的执行分两步 , LODGING$MANAGER 的索引范围查询 ( 得到所有符合条件记录的 ROWID) 和下一步同过 ROWID 访问表得到 LODGING 列的值 . 由于 LODGING$MANAGER 是一个非唯一性的索引 , 数据库不能对它执行索引唯一扫描 .
62
63由于 SQL 返回 LODGING 列 , 而它并不存在于 LODGING$MANAGER 索引中 , 所以在索引范围查询后会执行一个通过 ROWID 访问表的操作 .
64
65WHERE 子句中 , 如果索引列所对应的值的第一个字符由通配符 (WILDCARD) 开始 , 索引将不被采用 .
66
67SELECT LODGING
68
69FROM LODGING
70
71WHERE MANAGER LIKE ‘ % HANMAN’;
72
73在这种情况下, ORACLE 将使用全表扫描 .
74
75(待续)</tablespacename></indexname>