热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

从平衡树到oracleb-tree索引的原理探索

从平衡树到oracleb-tree索引的原理探索先话唠一下,oracle索引,有两类运用较广:1)b-tree:OLTP(面向交易)2)bitmap:OLAP(面向分析)步入正题,先搭建测试环境:[sql]SQL>createtablett...SyntaxHighligh

从平衡树到oracle b-tree索引的原理探索
 
先话唠一下,oracle索引,有两类运用较广:
    1)b-tree:OLTP(面向交易)
    2)bitmap:OLAP(面向分析)
    步入正题,先搭建测试环境:
[sql] 
SQL> create table tt as select * from dba_objects;  
  
表已创建。  
SQL> select count(*) from tt;  
  
  COUNT(*)  
----------  
     50441  
    www.2cto.com  
SQL> insert into tt select * from tt;  
  
已创建50441行。  
  
SQL> /  
  
已创建100882行。  
  
SQL> /  
  
已创建201764行。  
  
SQL> /  
  
已创建403528行。  
  
SQL> /  
  
已创建807056行。  
  
SQL> create index tt_index on tt(object_id) tablespace users;  
  
索引已创建。  
 
    把索引tt_index的结构给dump出来:
[sql] 
SQL> select object_id from dba_objects where object_name='TT_INDEX';  
    www.2cto.com  
 OBJECT_ID  
----------  
     53042  
SQL> alter session set events 'immediate trace name treedump level 53042';  
  
会话已更改。  
  
SQL> show parameter user_dump_dest  
  
NAME                                 TYPE  
------------------------------------ ----------------------  
VALUE  
------------------------------  
user_dump_dest                       string  
G:\ORACLE\PRODUCT\10.2.0\ADMIN  
\ORCL\UDUMP  
SQL> select distinct sid from v$mystat;  
  
       SID  
----------  
       147  
  
SQL> select paddr from v$session where sid=147;  
  
PADDR  
--------  
CA280DDC  
  
SQL> select spid from v$process where addr='CA280DDC';  
    www.2cto.com  
SPID  
------------------------  
5360  
    到udump,把进程号为5360的文件打开,部分内容如下:
 
[sql] 
*** 2012-08-07 01:21:34.944  
*** ACTION NAME:() 2012-08-07 01:21:34.902  
*** MODULE NAME:(SQL*Plus) 2012-08-07 01:21:34.902  
*** SERVICE NAME:(SYS$USERS) 2012-08-07 01:21:34.902  
*** SESSION ID:(147.92) 2012-08-07 01:21:34.902  
----- begin tree dump  
branch: 0x10001bc 16777660 (0: nrow: 7, level: 2)  
   branch: 0x100595f 16800095 (-1: nrow: 578, level: 1)  
      leaf: 0x10001bd 16777661 (-1: nrow: 513 rrow: 513)  
      leaf: 0x10001be 16777662 (0: nrow: 513 rrow: 513)  
      leaf: 0x10001bf 16777663 (1: nrow: 513 rrow: 513)  
      leaf: 0x10001c0 16777664 (2: nrow: 513 rrow: 513)  
      leaf: 0x10001c1 16777665 (3: nrow: 513 rrow: 513)  
      leaf: 0x10001c2 16777666 (4: nrow: 513 rrow: 513)  
      leaf: 0x10001c3 16777667 (5: nrow: 484 rrow: 484)  
      leaf: 0x10001c4 16777668 (6: nrow: 478 rrow: 478)  
      leaf: 0x10001c5 16777669 (7: nrow: 478 rrow: 478)  
      leaf: 0x10001c6 16777670 (8: nrow: 478 rrow: 478)  
      leaf: 0x10001c7 16777671 (9: nrow: 478 rrow: 478)  
      leaf: 0x10001c8 16777672 (10: nrow: 478 rrow: 478)  
      leaf: 0x10001ca 16777674 (11: nrow: 481 rrow: 481)  
      leaf: 0x10001cb 16777675 (12: nrow: 478 rrow: 478)  
      leaf: 0x10001cc 16777676 (13: nrow: 478 rrow: 478)  
      leaf: 0x10001cd 16777677 (14: nrow: 478 rrow: 478)  
      leaf: 0x10001ce 16777678 (15: nrow: 478 rrow: 478)  
      leaf: 0x10001cf 16777679 (16: nrow: 478 rrow: 478)  
  www.2cto.com  
    由此可证明:b-tree中的b是balance,是棵平衡树。否则,一个branch下面只有两个leaf,才是二叉树。
    上面:0x10001bd (16进制)和16777661(10进制)这两个,其实,是一样的。
 
[sql] 
SQL> select to_number('10001bd','xxxxxxx') from dual;  
  
TO_NUMBER('10001BD','XXXXXXX')  
------------------------------  
                      16777661  
    而且,16777661包含两部分:文件号、数据块号。意指:这个地址是哪个数据文件上的第几个块  www.2cto.com  
 
[sql] 
SQL> select dbms_utility.data_block_address_file( 16777661) from dual  
  
DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(16777661)  
----------------------------------------------  
                                             4  
  
SQL> select dbms_utility.data_block_address_block( 16777661) from dua  
  
DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(16777661)  
-----------------------------------------------  
                                            445  
    由上,可得:4号文件的第445个块
    将tt_index的内容给dump出来一下:
[sql] 
SQL> alter system dump datafile 4 block 445;  
  
系统已更改。  
  www.2cto.com  
    部分内容摘入如下:
[sql] 
row#0[8024] flag: ------, lock: 0, len=12  
col 0; len 2; (2):  c1 03  
col 1; len 6; (6):  01 00 01 ac 00 2d  
row#1[8012] flag: ------, lock: 0, len=12  
col 0; len 2; (2):  c1 03  
col 1; len 6; (6):  01 00 05 36 00 40  
row#2[8000] flag: ------, lock: 0, len=12  
col 0; len 2; (2):  c1 03  
col 1; len 6; (6):  01 00 08 01 00 1b  
row#3[7988] flag: ------, lock: 0, len=12  
col 0; len 2; (2):  c1 03  
col 1; len 6; (6):  01 00 0a a2 00 2d  
row#4[7976] flag: ------, lock: 0, len=12  
col 0; len 2; (2):  c1 03  
col 1; len 6; (6):  01 00 0d 69 00 48  
    tt表最小的object_id为2,对应的便是row#0[8024],那么2在oracle中的16进制是如何存储的呢?
[sql] 
SQL> select dump(2,16) from dual;  
  
DUMP(2,16)  
----------------------------------  
Typ=2 Len=2: c1,3  
  www.2cto.com  
    由此,可知:2的存储是c1 03.也就是,第0行的第一列存储的值是2.
    意味着,在索引的叶子节点里,我们在哪一列上创建索引,其实,oracle就是把该列的值保存到索引的叶子节点里。
    索引里第一行第2列16进制数:01 00 01 ac 00 2d和rowid有啥关系呢?
[sql] 
SQL> select object_id,rowid from tt  
  2   where object_id=2  
  3   order by object_id,rowid;  
  
 OBJECT_ID ROWID  
---------- ------------------  
         2 AAAM8xAAEAAAAGsAAt  
         2 AAAM8xAAEAAAAU2ABA  
         2 AAAM8xAAEAAAAgBAAb  
         ...  
    其实,索引里第一行第2列16进制数:01 00 01 ac 00 2d表示的是rowid里面后三部分,也就是:fno、bno、rno。
  www.2cto.com  
    rowid:AAAM8x  AAE  AAAAGs  AAt。通过进制的转换,AAE  AAAAGs  AAt和01 00 01 ac 00 2d是一样的。
    为什么只有后三个部分呢?说白点,书的目录会把书名给包括进去吗?书名就是对象编号、目录就是索引。
    到此,我们把索引的内部结构给构造出来:
    object_id  rowid(后三部分)
    ...             ...
 
    草图如下:

 
作者 linwaterbin

推荐阅读
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • SQL中UPDATE SET FROM语句的使用方法及应用场景
    本文详细介绍了SQL中UPDATE SET FROM语句的使用方法,通过具体示例展示了如何利用该语句高效地更新多表关联数据。适合数据库管理员和开发人员参考。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 在使用SQL Server进行动态SQL查询时,如果遇到LIKE语句无法正确返回预期结果的情况,通常是因为参数传递方式不当。本文将详细探讨这一问题,并提供解决方案及相关的技术背景。 ... [详细]
  • 本文介绍如何通过创建替代插入触发器,使对视图的插入操作能够正确更新相关的基本表。涉及的表包括:飞机(Aircraft)、员工(Employee)和认证(Certification)。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
author-avatar
一二三八嘎
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有