Oracle的索引是以平衡树的方式组织存储的:保存的是索引列的值,以及该行的rowid的一部分(文件号,块号,行号)

下面我们通过例子来了解一下:

1,create table test(id int,name varchar2(20))

insert into test values(1,'A');

insert into test values(2,'B');

begin

for i in 3..2000 loop

insert into test values(i,'t'||i);

end loop;

end;

2,create  index idx_test on test(id)

3,得到这个index的object_id:

SQL> select object_id  from dba_objects where object_name='IDX_TEST';

OBJECT_ID

----------

     74560

4,将索引dump到trace文件中

alter session set events 'immediate trace name treedump level 74560';

看到结果:有两层,5个叶子节点

----- begin tree dump

branch: 0x1000c93 16780435 (0: nrow: 5, level: 1)

   leaf: 0x1000c94 16780436 (-1: nrow: 485 rrow: 485)

   leaf: 0x1000c95 16780437 (0: nrow: 479 rrow: 479)

   leaf: 0x1000c96 16780438 (1: nrow: 479 rrow: 479)

   leaf: 0x1000c97 16780439 (2: nrow: 479 rrow: 479)

   leaf: 0x1000c98 16780440 (3: nrow: 78 rrow: 78)

----- end tree dump

0x1000c93 :转为为10进制就是16780435

branch 表示的是 branch block ,它后面跟了一个十六进制表示的DBA(data block address),以及用10进制表示的DBA 

DBA 之后表示在同一层次的相对位置(root 从0开始,branch 以及leaf从 -1开始) 

nrow  表示块中包含了多少条目(包括delete的条目) 

rrow  表示块中包含的实际条目(不包括delete的条目) 

level 表示从该block到leaf的深度(leaf没有 level)

这个 branch block 的 level 为1,也就是说 从这个branch block 到 leaf block 的深度为1,根据前面的查询,这个索引的Blevel为1

验证索引的高度:

SQL> select index_name, PREFIX_LENGTH, BLEVEL, LEAF_BLOCKS from user_indexes where index_name='IDX_TEST';

INDEX_NAME         PREFIX_LENGTH  BLEVEL LEAF_BLOCKS

------------------------------ ------------- ---------- -----------

IDX_TEST           1    5

可以看到高度为1,leaf block为5

BLEVEL* NUMBER   B*-Tree level: depth of the index from its root block to its leaf blocks. A depth of 0 indicates that the root block and leaf block are the same.

LEAF_BLOCKS* NUMBER   Number of leaf blocks in the index

现在我来验证一下 branch: 0x1000c93 16780435 (0: nrow: 5, level: 1) 是不是 root block , 我查询这个 branch 的 DBA

SQL> select dbms_utility.data_block_address_file('16780435') FILE_ID,

       dbms_utility.data_block_address_block('16780435') BLOCK_ID

  from dual;  2    3

FILE_ID   BLOCK_ID

---------- ----------

  4  3219

Btree 索引的 root block总是segment header+1,所以我查询该索引的段头 

 

SQL>  select header_file,header_block from dba_segments where segment_name='IDX_TEST';

HEADER_FILE HEADER_BLOCK

----------- ------------

   4     3218

证明branch: 0x1000c93 16780435 (0: nrow: 5, level: 1) 就是root块,其实 treedump第一个 branch block 就是 root block

######################################################################################

到此时为止,已经从dump信息得出了索引的高度和第一个branch block就是root block的结论                                                                                 

######################################################################################

----- begin tree dump

branch: 0x1000c93 16780435 (0: nrow: 5, level: 1)

   leaf: 0x1000c94 16780436 (-1: nrow: 485 rrow: 485)

   leaf: 0x1000c95 16780437 (0: nrow: 479 rrow: 479)

   leaf: 0x1000c96 16780438 (1: nrow: 479 rrow: 479)

   leaf: 0x1000c97 16780439 (2: nrow: 479 rrow: 479)

   leaf: 0x1000c98 16780440 (3: nrow: 78 rrow: 78)

----- end tree dump

通过下面的转换可以看到上面这两个数据是可以相互转换的。

select to_number('1000c94','xxxxxxxxxxx') from dualSQL> ;

TO_NUMBER('1000C94','XXXXXXXXXXX')

----------------------------------

     16780436

SQL> select to_char('16780436','xxxxxxxxxxx') from dual;

TO_CHAR('167

------------

     1000c94

Oracle 中提供了dbms_utility来求的这个地址对应的文件号和块号(传入的参数是十进制的那个值).

查看这个leaf block对应的文件号和块号

select dbms_utility.data_block_address_file(16780436)fno,

dbms_utility.data_block_address_block(16780436) bkno from dual

SQL> select dbms_utility.data_block_address_file(16780436)fno,

dbms_utility.data_block_address_block(16780436) bkno from dual  2 

  3  ;

FNO  BKNO

---------- ----------

  4  3220

得到的是第4号文件的第3220块

SQL> select file_id,block_id,blocks from dba_extents where segment_name='IDX_TEST';

FILE_ID   BLOCK_ID   BLOCKS

---------- ---------- ----------

  4  3216        8

  4  3224        8

##################################################################################

这里得出了leaf 块存放的数据文件号和对应的块                                     

##################################################################################

5,将索引数据dump出来,dump 4号文件的3220块,alter system dump datafile 4 block 3220

row#0[8020] flag: ------, lock: 0, len=12

col 0; len 2; (2):  c1 02

col 1; len 6; (6):  01 00 0c 8f 00 00

row#1[8008] flag: ------, lock: 0, len=12

col 0; len 2; (2):  c1 03

col 1; len 6; (6):  01 00 0c 8f 00 01

row#2[7996] flag: ------, lock: 0, len=12

col 0; len 2; (2):  c1 04

col 1; len 6; (6):  01 00 0c 8f 00 02

row#3[7984] flag: ------, lock: 0, len=12

col 0; len 2; (2):  c1 05

col 1; len 6; (6):  01 00 0c 8f 00 03

以前三行为例,

row#0行号.

col 0第一列(本例中第一列为是id), len 2表示长度是2, (2)表示占了两个字节,c1 02是id的值(这里值是1的16进制表示)的存储表示.

col 1是rowid,01 00 0c 8f 00 00是rowid的一部分值,也是16进制的.,先要转换成2进制的,再通过各个位数代表的意义计算文件号,块号和和行号。

01 00 0c 8f 00 00 先转换为2进制:(注意前面先补足0)

10000000000001100100011110000000000000000

00000001 00000000 00001100 10001111 00000000 00000000

然后串起来之后前10位 00000001 00 表示文件号,=4

然后是接下来的22位 000000 00000000 00001100表示块号=3215

最后面的的16位表示行号=0

SQL> select rowid,

       id,

       dbms_rowid.rowid_relative_fno('AAASM/AAEAAAAyPAAA') fno,

       dbms_rowid.rowid_block_number('AAASM/AAEAAAAyPAAA') bkno,

       dbms_rowid.rowid_row_number('AAASM/AAEAAAAyPAAA') rno

  from test

 where id = 1;  2    3    4    5    6    7

ROWID      ID      FNO       BKNO    RNO

------------------ ---------- ---------- ---------- ----------

AAASM/AAEAAAAyPAAA     1        4       3215      0

上面的sql得到是4号文件3125块0行.证明索引里保存的为rowid的一部分信息。

总结:dump信息包括了索引的高度,leaf block指向数据块的地址(包括数据文件好和块号),记录了一部分的rowid信息

B*tree dump的更多相关文章

  1. ALV tree DUMP 问题处理-20180328

    Category ABAP Programming Error Runtime Errors MESSAGE_TYPE_X ABAP Program SAPLOLEA Application Comp ...

  2. oracle dump event

    一.Memory Dumps 1).Global Area ALTER SESSION SET EVENTS 'immediate trace name global_area level n'; 1 ...

  3. 如何获取数据块结构信息dump

    有个pub_department的表,索引为PK_PUB_DEPARTMENT. 1.找到object_id select   object_id from dba_objects s  where  ...

  4. dump iot表

    SQL> create user scan identified by scan default tablespace users; User created. SQL> grant db ...

  5. 理解 B*tree index内部结构

    转载请注明出处:http://write.blog.csdn.net/postedit/40589651 Oracle数据库里的B树索引就好象一棵倒长的树.它包括两种类型的数据块:一种是索引分支块,还 ...

  6. iot 表索引dump《2》

    iot表测试: 在create table语句后面使用organization index,就指定数据表创建结构是IOT.但是在不指定主键Primary Key的情况下,是不允许建表的. create ...

  7. Oracle dump 分析secondary key

    验证secondary key 含有主键列数据 SQL> select object_name,object_id,OBJECT_TYPE from user_objects; OBJECT_N ...

  8. Oracle heap 表的主键 dump 分析

    1. 创建heap 表: create table t1 (id char(10) primary key,a1 char(10),a2 char(10),a3 char(10)); SQL> ...

  9. 【原创】xgboost 特征评分的计算原理

    xgboost是基于GBDT原理进行改进的算法,效率高,并且可以进行并行化运算: 而且可以在训练的过程中给出各个特征的评分,从而表明每个特征对模型训练的重要性, 调用的源码就不准备详述,本文主要侧重的 ...

随机推荐

  1. 从入行到现在(.net)

    每次写东西都不知道怎么去开头.因为一想到要写东西.脑子里面浮现出来的开头就太多. 进园子很久从开始只是关注别人讲的技术,别人讲的基础,到现在更多的去看大家的随笔和新闻.这两年我从零基础的外行人逐渐进入 ...

  2. JAVA spring 常用包作用

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  3. 学习笔记_Java_day13_JSP三大指令()

    JSP指令 1        JSP指令概述 JSP指令的格式:<%@指令名 attr1=”” attr2=”” %>,一般都会把JSP指令放到JSP文件的最上方,但这不是必须的. JSP ...

  4. 如何诊断oracle数据库运行缓慢或hang住的问题

    为了诊断oracle运行缓慢的问题首先要决定收集哪些论断信息,可以采取下面的诊断方法:1.数据库运行缓慢这个问题是常见还是在特定时间出现如果数据库运行缓慢是一个常见的问题那么可以在问题出现的时候收集这 ...

  5. Block中的引用循环

    原文地址:http://www.cnblogs.com/lujianwenance/p/5910490.html Block在实际的开发中非常的常用,事件回调.传值.封装成代码块调用等等.很多人都对b ...

  6. 关于MDCSwipeToChooseView的应用

    本人因为项目中某个页面的功能需要,用到了MDCSwipeToChooseView,就在网上查阅了相关的资料,资源有很多,但应该都是同一个人上传的,code4还有git上都有,但下载demo下来后运行不 ...

  7. ORACLE 关连更新 update select

    总结:  关键的地方是where 语句的加入. 在11G中, 如果不加11G , 或造成除匹配的行数更新为相应的值之后, 其余的会变成负数. 所以, 测试的办法就是:  先查看需要更新的数量即连接的数 ...

  8. 在jsp中选中checkbox后 将该记录的多个数据获取,然后传到Action类中进行后台处理 双主键情况下 *.hbm.xml中的写法

    在jsp中选中checkbox后 将该记录的多个数据获取,然后传到Action类中进行后台处理 双主键情况下 *.hbm.xml中的写法   ==========方法1: --------1. 选相应 ...

  9. MFC类的结构

    1. CObject类,MFC库中绝大部分类的基类,封装了MFC中的最基本机制. 运行时类信息机制/动态创建机制/序列化机制等... 2. CCmdtarget - 消息映射机制最基类 3. CWin ...

  10. Java调用.Net WebService参数为空解决办法 (远程)调试webservice方法 转

    Java调用.Net WebService参数为空解决办法 (远程)调试webservice方法   同事遇到一个很囧的问题,java调,netwebservice的时候,调用无参数方法成功,调用有参 ...