Oracle性能分析9:重建索引(二)

2014-11-24 12:24:55 · 作者: · 浏览: 1
------- ---------- total 3 0.01 1.81 56 224 0 1 Misses in library cache during parse: 1 Optimizer mode: ALL_ROWS Parsing user id: 5 Rows Row Source Operation ------- --------------------------------------------------- 1 TABLE ACCESS BY INDEX ROWID TEST (cr=224 pr=56 pw=0 time=1538212 us) 1 INDEX RANGE SCAN IDX_TEST (cr=223 pr=56 pw=0 time=1527442 us)(object id 58594) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 SQL*Net message from client 2 0.79 0.83 db file sequential read 56 0.03 0.41 ********************************************************************************

查询使用了索引范围扫描,虽然整个表只有一条数据,但由于索引中的索引碎片,导致索引扫描任然读取了56个数据块。下面重建该索引:

alter index IDX_TEST rebuild;

然后按上面的方法生成并查看索引信息:

LF_ROWS	LF_BLKS	DEL_LF_ROWS
-----------------------------------
1	1	0

可以看出索引碎片消失。

注意事项:

1)执行索引分析会锁定表,直到索引分析完毕才解除锁定;
2)在大多数情况下,Oracle会尽可能的重用索引中已删除条目的空间。

为什么重建索引

实际上,重建(rebuild)索引就是重新创建索引,但它比删除原索引再重新创建索引的做法要好,因为在重建索引时存储空间已分配给索引,而不需要再指定索引创建语句。
关于索引重建有很多依据,但其中有一些并不准确,下面列举了一些:
1)Oracle的B树索引随着时间的推移变得不平衡
由于B树索引的根块和所有的叶块之间的高度始终是一致的,所以这不正确。
2)索引中被删除的空间无法重用
实际上Oracle会重用被删除的空间。
3)达到一定层数的索引是低效的
索引的层数取决于索引有多少条目,重建不能解决问题。
4)具有糟糕的聚蔟因子的索引,可以通过重建修复
重建索引并不能改变表中数据行或索引的顺序,因此聚蔟因子(见使用索引的聚蔟因子)完全不受索引重建影响。如果想改进聚蔟因子,实际上需要重建表。
那么具体为什么重建索引呢?

当索引不可用时,应该重建索引,但我们是否应该重建索引来消除索引碎片呢?
当你的查询大部分都是通过索引访问读取单个行,那么重建索引对性能影响很小。但对于范围查询,由于大量的索引碎片会导致查询增加大量的无效IO,因此重建索引是有意义的,即使Oracle会重用索引碎片,但重建索引也可以使索引变得更加紧凑,从而提高查询的效率。

重建索引

上面已经使用到重建索引的方法:

alter index IDX_TEST rebuild;

但重建索引的过程中会对表加锁,阻止其他对表的操作,直到索引重建完成。从Oracle 10g开始,Oracle提供了在线重建索引的方法:

alter index IDX_TEST rebuild online;
 
 

在线重建索引不会再导致索引锁定。

重建分区索引则需要带上分区信息:

alter index IDX_TEST rebuild partition partition_name online;

Oracle也为创佳和重建索引提供了一些参数,用于提高创建和重建索引的效率。

并行创建或重建索引

为了创建索引,数据库需要进行全表扫描,并行创建可以加快索引的创建速度,速度的提升由并行度和CPU数量决定:

create index IDX_TEST on test(id) parallel 4 online;

也可以用于重建索引:

alter index IDX_TEST rebuild parallel 4 online;

需要注意的是这个操作将使索引的并行度(见使用索引)永远变为这个值,如下:

select degree from user_indexes where index_name = 'IDX_TEST';

DEGREE
--------------------
4

如果打算让数据库在处理你的索引时使用并行机制,则正好,否则,你需要在执行了并行创建和重建操作后禁用并行:

alter index IDX_TEST noparallel;

如果忘记禁用并行,可能会导致严重的性能问题。

在索引创建或重建时避免生成重做信息

不把创建或者重建的索引项写入重做日志,可以大大缩短索引创建或重建的时间:

create index IDX_TEST on test(id) nologging online;

也可以在重建索引时使用:

alter index IDX_TEST rebuild nologging online;

nologging不仅可以极大地提高性能,而且不填充多个重做日志文件,节省空间。

压缩索引

在非唯一索引中使用压缩,可以减少重复键占用的空间:

compress <数字,并小于等于索引包括的字段值>

一个实例如下:

create index IDX_TEST on test(id) compress 1 online;

同样可以用于重建索引:

alter index IDX_TEST rebuild compress 1 online;