关于Oracle索引树的结构以及它们对Oracle性能调优是否重要存在大量的
激烈的争论
而且已经有很多文章试图来描述这些重要的Oracle性能工具的内部工作机制
关于这个论题也出现了一些新书
例如由
国际Oracle用户组
(IOUG)主席Kim Floss所着的《Oracle索引管理秘诀》和《Oracle SQL 性能调优和
基于代价的优化器
内幕》
正如我们知道的Oracle提供了大量索引结构每种索引结构都有其好处和不足
* B树索引从最早的Oracle发行版本开始Oracle就一直使用的标准树索引就是B树索引
* 位图索引当某个索引列含有很少数量的不同的值(即低基数)时使用位图索引这对于那些只读数据库而言速度超快但对需要经常性更新的系统不适合
* 位图连接索引这是针对来自其他表的数据列出现在某个连接表的多列索引时使用的索引下面是在from子句和where子句中使用类似SQL的创建索引的惟一语法
create bitmap index
part_suppliers_state
on
inventory( partspart_type supplierstate )
from
inventory i
parts p
supplier s
where
ipart_id=ppart_id
and
isupplier_id=psupplier_id;
尽管有关索引重建的争论仍在激烈进行着但还是存在每个人都认可的索引管理的某些领域在内部机制上一个Oracle B树索引的结构和一个UNIX I结点的结构非常相似索引中的每个数据块都是索引树中的一个结点位于最底部的结点(叶数据块)包含一对符号键和行ID值
Oracle b树索引
为了正确管理这些数据块Oracle控制着每个数据块中指针的分配随着一棵Oracle树的增长(通过往表里插入新行)Oracle会填充这个数据块当这个数据块满时Oracle会分裂它创建新的索引结点(数据块)来管理索引内的符号键
因此一个Oracle索引块可能包含以下两种类型的指针
* 指向其他索引结点(数据块)的指针
* 指向数据库表中特定行的行ID指针
Oracle管理着索引块内指针的分配这就是为什么我们不能为索引指定一个PCTUSED值(自由列表重链接门槛)的原因当我们检查一个索引块的结构时我们发现每个索引结点内部条目的数量是下面两个值的一个函数
. 符号键的长度
. 索引表空间的块尺寸
由于块尺寸影响每个索引结点内部的符号键的数量可以推理出块尺寸对一棵索引树的结构也会有影响在其他条件相同的情况下采用K的大数据块能容纳更多的符号键从而能够比在K表空间中创建的相同的索引更加平整采用大的数据块也将减少索引访问期间一致获取的数量从而提高分散读访问的性能
索引中的每个数据块包含索引树中的结点位于最底部的结点(叶数据块)包含一对符号键和行ID值随着一棵Oracle树的增长(通过往表里插入新行)Oracle会填充这个数据块当这个数据块满时Oracle会分裂它创建新的索引结点(数据块)来管理索引内的符号键因此一个Oracle索引块可能包含指向其他索引结点或行ID/符号键对的指针
索引行为和Oracle块尺寸
由于块尺寸影响每个索引结点内部的符号键的数量可以推理出块尺寸对一棵索引树的结构也会有影响在其他条件相同的情况下采用K的大数据块能容纳更多的符号键从而能够比在K表空间中创建的相同的索引更加平整
今天大多数Oracle性能调优专家都利用Oracle提供的多种块尺寸的特色因为它提供了缓沖区隔离和以最合适块尺寸来存放对象从而减少缓沖区浪费的能力一些Oracle基准测试的世界记录都使用很大的数据缓沖区和多种块尺寸
根据《Oracle数据库管理员认证Oracle 认证数据库管理专家教师指南》一书的作者Christopher Foot的一篇文章更大的块尺寸在某些情况下非常有帮助
更大的块尺寸意味着在B树索引的分支结点中有更多的空间来存储符号键从而可以降低树的高度和提高索引查询的性能
在任何情况下似乎有证据表明块尺寸影响树的结构这为数据块影响树的结构提供了有力支持
你可以使用大数据块()缓沖区来存储来自作为重复性大规模扫描对象的索引或表中的数据这真的会提高性能么?一个小的但透漏内情的测试能回答这个问题
在这个测试中将对某个使用K数据块尺寸的Oracle i数据库执行以下查询这个数据库同时也使用K缓沖区和K大小的表空间
select
count(*)
from
eradminadmission
where
patient_id between and ;
表eradminadmission含有行数据并在patient_id列上建立了一个索引对上面的查询语句执行EXPLAIN命令揭示出它使用索引范围扫描来产生想要的目的结果
Execution Plan
SELECT STATEMENT Optimizer=CHOOSE
(Cost= Card= Bytes=)
SORT (AGGREGATE)
INDEX (FAST FULL SCAN) OF ADMISSION_PATIENT_ID
(NONUNIQUE) (Cost= Card= Bytes=)
使用位于一个标准K表空间的索引来执行这个查询(两次以消除分析活动并缓沖任何数据)产生了以下实时统计信息
Statistics
recursive calls
db block gets
consistent gets
physical reads
redo size
bytes sent via SQL*Net to client
bytes received via SQL*Net from client
SQL*Net roundtrips to/from client
sorts (memory)
sorts (disk)
rows processed
为了测试新的K缓沖区和K表空间的效果将使用K的表空间来重建这个查询所用的索引K的表空间和原来的K的表空间相比除了更大的块尺寸其他特性一模一样
alter index
eradminadmission_patient_id
rebuild nologging noreverse tablespace indx_k;
一旦在K表空间中建立好这个索引就再次执行这个查询(同样也是执行两次)会产生以下的运行时统计信息
Statistics
recursive calls
db block gets
consistent gets
physical reads
redo size
bytes sent via SQL*Net to client
bytes received via SQL*Net from client
SQL*Net roundtrips to/from client
sorts (memory)
sorts (disk)
rows processed
正如你所看到的逻辑读操作的次数被减少了一半仅仅是由于使用了新的K表空间和K数据缓沖区很显然正确使用新的数据缓沖区和Oraclei及其以上版本的多种块尺寸表空间的特色很值得在你的数据库中被试验和研究
定期进行索引重建?
争论的另外一个领域是是否存在一些确定的规则可以用来确定何时能够从索引重建中获取性能提高许多使用Oracle的企业都定期进行索引重建并声称在他们和重建他们的Oracle B树索引后获得了相当大的速度提升
在Oracle世界上展示了Sushil Kumar所着的一篇题为Oracle数据库g自我管理的数据库的文章Kumar声明说Oracleg的自动维护任务(AMT)特色将自动检测并重建潜在的最优化的索引
自动工作负载信息库(AWR)给oracleg提供了关于数据库各种使用情况的详细信息通过分析存储在自动工作负载信息库(AWR)中的信息g数据库可以决定是否需要执行数据库性能维护任务比如优化器统计数字的刷新重建索引等等 以自动维护任务AMT为基础oracle数据库可以自动执行这些操作
尽管如此仍有不少反对定期重建索引的论点一些oracle内部的专家坚持认为oracle索引在空间重用和访问速度上是非常高效的b-树索引在极少情况下才需要被重建他们坚持认为逻辑输入输出的减少应该是可测量的并且如果重建索引是有好处的某些人应该已经提出了可以证明的规则
结论
多种数据块尺寸的特色能够提高Oracle索引的性能而且在某些情况下重建索引可以提高查询速度这是显而易见的人们期望新的Oracleg自动维护任务AMT允许自动检测并重建潜在的最优化索引结构
如果你喜欢Oracle性能调优技巧你或许会喜欢Rampant科技出版社出版的我的最新着作创建具有自我调优功能的Oracle数据库它仅售美元(我认为收取书费是不对的!)