ORACLE SQL性能优化系列 (八)

** 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>
Published At
Categories with 数据库类
comments powered by Disqus