网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>数据库技术>>Oracle技术>>Oracle开发>查看文档  
  由浅至深讲解oracle数据库 b-tree索引 (1)     
  文章作者:未知  文章来源:赛迪网技术社区  
  查看:80次  录入:管理员--2008-04-16  
 

【赛迪网-it技术报道】假如聚簇因子过大,那么重建索引可能会有好处,聚簇因子应该接近块的数量,而非行的数量。

b-tree索引:

?索引会随着时间的增加而变的不平衡;

?删除的索引空间不会被重用;

?随着索引层数的增加,索引将会变得无效并需要重建;

?聚簇因子差,索引需要重建;

?为了提高性能,索引需要经常重建;

索引基础

?一个更新由一个删除和一个插入组成;

?页块由索引条目(row header(2/3b)|length(1b)|indexed data value(nb)|length(1b)|rowid(6b))和相应的rowid组成;

?每个页块包含两个指针分别前面的页块和后面页块;

treedump

alter session set events ‘immediate trace name treedump level index_object_id’;

----- begin tree dump

branch: 0x424362 4342626 (0: nrow: 2, level: 1)

leaf: 0x424363 4342627 (-1: nrow: 540 rrow: 540)

leaf: 0x424364 4342628 (0: nrow: 461 rrow: 461)

----- end tree dump

以上dump包含的信息如下:

块类型:branch(分支块);leaf(页块);

块地址:0x424362 4342626;

nrow:索引条目的数量;

rrow:当前块中的索引条目数量;

level:分支块等级(页块隐示为0);

block dump

alter system dump datafile x block x;

alter system dump datafile x block min x1 block max x2

start dump data blocks tsn: 0 file#: 1 minblk 148538 maxblk 148538

buffer tsn: 0 rdba: 0x0042443a (1/148538)

scn: 0x0000.00162a95 seq: 0x01 flg: 0x04 tail: 0x2a950601

frmt: 0x02 chkval: 0x8b5c type: 0x06=trans data

block header dump: 0x0042443a

object id on block? y

seg/obj: 0xd1fe csc: 0x00.162a95 itc: 2 flg: o typ: 2 - index

fsl: 0 fnx: 0x42443b ver: 0x01

itl xid uba flag lck scn/fsc

0x01 0x0005.02a.00000332 0x008005cb.020e.01 cb-- 0 scn 0x0000.00162a92

0x02 0x0008.011.00000346 0x008002e6.0163.03 c--- 0 scn 0x0000.00162a93

该dump包含的信息如下:

rdba:分支块的相对数据库块地址(文件号/块号);

scn:块最后改变的scn号;

type:块类型;

seq:块改变的数量;

seg/obj: 16进制对象id;

typ:段类型;

itl:相关的事务槽(页块默认为2),包括槽id,事务id,撤销块地址,标记,锁信息,和事务scn;

通过rba确定数据文件号和块号:

select dbms_utility.data_block_address_file(rba),

dbms_utility.data_block_address_block(rba)

from dual;

通用的索引块头

header address 153168988=0x9212c5c

kdxcolev 0

kdxcolev flags = - - -

kdxcolok 1

kdxcoopc 0x89: opcode=9: iot flags=--- is converted=y

kdxconco 2

kdxcosdc 2

kdxconro 254

kdxcofbo 544=0x220

kdxcofeo 4482=0x1182

kdxcoavs 3938

kdxcolev:索引级别(0代表页块);

kdxcolok:标示结构块事块是否发生;

kdxcoopc:内部操作码;

kdxconco:索引列数量,包括rowid;

kdxcosdc:块中索引结构改变的数量;

kdxconro:索引条目的数量,不包括kdxbrlmc指针;

kdxcofbo:块中空闲空间的开始位置;

kdxcofeo:块中空闲空间的结束位置;

kdxcoavs:块中的可用空间数量(kdxcofbo-kdxcofeo);

分支头区域

kdxbrlmc 8388627=0x800013

kdxbrsno 92

kdxbrbksz 8060

kdxbrlmc:如果索引值小于第一个值(row#0),则为该索引值所在的块地址;

kdxbrsno:最后更改的索引条目;

kdxbrbksz:可使用的块空间;

叶块头区域

kdxlespl 0

kdxlende 127

kdxlenxt 4342843=0x42443b

kdxleprv 4342845=0x42443d

kdxledsz 0

kdxlebksz 8036

kdxlespl:块拆分时被清除的未提交数据的字节数;

kdxlende:被删除的条目数;

kdxlenxt:下一个页块的rba;

kdxleprv:上一个页块的rba;

kdxlebksz:可使用的块空间(默认小于分支的可用空间);

分支条目

row#0[7898] dba: 4342821=0x424425

col 0; len 3; (3): c2 61 03

col 1; term

row#1[7214] dba: 4342873=0x424459

col 0; len 4; (4): c3 04 02 17

col 1; term

行号,[块中的起始位置] dba;

列号,列长度,列值;

brach中的每个entry有2个columns:

一个是child blocks中的最大值,另一个是指向的下一层block的address'

但是某些时候可能会有一些比较奇怪的结果:

row#0[7025] dba: 4342908=0x42447c

col 0; len 1024; (1024):

41 20 20 20 …20

col 1; len 4; (4): 00 42 44 73

----- end of branch block dump -----

叶条目

row#38[5014] flag: ----s-, lock: 2, len=14

col 0; len 4; (4): c3 04 61 55

col 1; len 6; (6): 00 42 43 db 00 a1

row#39[5028] flag: ---ds-, lock: 2, len=14

行号[在块中的开始位置] 各种标记(锁信息,删除信息);

索引列号,长度,值。其中6个字节的为rowid号,将其转换为二进制,算法结果为:

前10 bit代表了file_id

中22 bit代表了block_id

后16 bit代表了row_id;

通过文件号和块号算出的结果为创建该索引的表的块。

奇怪的是,为什么索引中的rowid不能直接找到obj_id?

因为索引段对应的数据段在 一开始就知道,因为是先知道数据段才找到索引段,然后

根据索引段内容去搜索数据段内容,所以索引段中 rowid 不必包含 data_object_id 信息。

如果索引是建立在非分区表上,或者是分区表上的 local 索引,使用的是6 bytes的 restricted rowid。如果索引是建立在分区表上的 global index,则使用 10bytes 的 extended rowid,这样可以区分索引指向哪个分区表。

更新/重用索引条目

当更新了索引条目后,dump如下:

kdxconco 2

kdxcosdc 0

kdxconro 2

kdxcofbo 40=0x28

kdxcofeo 8006=0x1f46

kdxcoavs 7966

kdxlespl 0

kdxlende 1

kdxlenxt 0=0x0

kdxleprv 0=0x0

kdxledsz 0

kdxlebksz 8036

row#0[8021] flag: ---d-, lock: 2 => deleted index entry

col 0; len 5; (5): 42 4f 57 49 45

col 1; len 6; (6): 00 80 05 0a 00 00

row#1[8006] flag: -----, lock: 2

col 0; len 5; (5): 5a 49 47 47 59 => new index entry

col 1; len 6; (6): 00 80 05 0a 00 00

更新后,将包含一个删除的条目,一个新的条目。在随后的插入中,如果新插入的索引条目能够放到被删除的索引条目的位置上,就会直接重用这个条目。根据索引值来决定。

所谓重用,是对row 的重用,而不是对row所在物理存储(或说物理位置)的重用。索引是按照indexed value对row进行排序的。有新的row被插入,首先按照value排序,将他放在合适的row list中,如果他的位置正好原来有个row被删掉了,则重用这个row在row list中的位置。至于物理存储上,则可能根据版本不同会有不同。在10.2中,我做的测试并没有向下开辟空间。

结论:

?到叶块中的任何插入都将移除所有被删除的条目;

?删除的空间在随后的写中被清除;

?删除的空间在延迟块清除中被清除;

?全空块被放在空闲列表,可以重用;

索引统计

?dba_indexes

?dbms_stats

?index_stats

-- analyze index index_name validate structure;

--分析资源,锁;

?v$segment_statistics

statistics_level = typical (or all)

注意事项:

blevel (dba_indexes) vs. height (index_stats)

blocks allocated,但未必使用;

lf_rows_len包含行负载(单列索引12个字节)

pct_used索引结构中当前使用的空间:(used_space/btree_space)*100

绝大多数索引统计包含删除的条目:

non-deleted rows = lf_rows ? del_lf_rows

pct_used by non-deleted rows = ((used_space ? del_lf_rows_len) / btree_space) * 100

 
 
上一篇: 深入了解缓冲日志文件i/o重要性能问题    下一篇: 解决表空间填充满时出现的ora-1652错误 (1)
  相关文档
实例讲解如何查找某个对象的定义情况 (1) 03-13
Oracle数据库最重要的部分之一数据字典 09-29
三步教会你掌握oracle外表(external table) 08-18
讲解"oracle"下导出某用户所有表的方法 02-02
解读oracle11g在商业银行的三大应用亮点 10-14
Oracle OCCI的一个简单的包装类的实现 04-23
教你在不同数据库环境下读取前n条记录数 07-14
诊断全局错误时如何在系统级进行设置 05-16
如果有输出参数则必须使用output做修饰符 04-01
清除Oracle中无用索引 改善DML性能 04-11
深入研究Oracle数据库中空间管理的方法 06-10
调整oracle应用系统性能的原则和方法 (1) 01-25
教你如何快速转移Oracle中海量数据 04-11
讲解数据库中行级转换成列级的应用案例 04-08
exp的版本高于数据库版本导出时出现报错 03-03
oracle的三种备份方式具有不同的恢复特性 06-17
Oracle DBA数据库日常维护完全手册 04-23
教你删除oracle数据库中重复没用的数据 09-10
全面解析oracle体系结构的两个重要概念 (1) 05-13
如何使用改变跟踪技术加速Oracle递增备份 05-27
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
厦门(总部):13616026886 福州:0591-87655121
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息