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