- 浏览: 560385 次
- 性别:
- 来自: 杭州
-
文章分类
- 全部博客 (340)
- Spring (4)
- Hibernate (2)
- Linux (34)
- Oracle (145)
- Eclipse (1)
- UML (1)
- HTML&&JAVASCRIPT (11)
- JAVA (33)
- 设计模式 (1)
- 版本控制 (1)
- wrap框架 (3)
- IBATIS (5)
- Ruby (1)
- DWR (1)
- MINA (11)
- JBPM (2)
- 缓存技术 (4)
- 网络 (3)
- 应用服务器 (1)
- GWT (5)
- 杂谈 (2)
- ICE (4)
- XML (2)
- ArcGis (2)
- Flex (8)
- junit单元测试 (1)
- SNMP (1)
- 存储 (1)
- office (1)
- MongoDB (0)
- Greenplum (3)
- 管理点滴 (1)
- C++ (6)
- 网络入门 (3)
- Tomcat (7)
- JMX (0)
- webservice (1)
- Oracle的10046事件 (1)
- Library cache内部机制详解 (1)
- expdp通过dblink来导入 (1)
最新评论
-
yuanliangding:
有没有关于mock的更多知识。
基于mock对象和JUnit框架简化Spring Web组件单元测试 -
saup007:
ssh端口不是22,怎么搞呢?
Greenplum 学习笔记 -
springmvc-freemarker:
java开源项目源码实例下载
Apache上全部JAVA开源项目简介 -
bobbell:
哇塞,你真厉害,整理的非常全面。我是一个java barcod ...
Greenplum 学习笔记 -
wsj55133245513324:
这不是bug,你将日志级别从debug提升到INFO 就好了 ...
Spring,smppapi,apache mina, ssl快速实现安全的smpp(5)
[分享] 复合索引branch block上存储几个列的信息
这是很早之前研究的问题,已经忘记了是什么案例导致去研究这个问题。
不过这个问题本省就很有意思,当在两个或者多个列上创建索引时,究竟branch block中会纪录几个列的信息?
首先我们知道branch block中存储结构大致是这样的 pointer - value - pointer - value - pointer.其中pointer指向leaf block或者下一层branch block.
那么这个value的值就是为了区分左右指针所指向的两个leaf block中(或者下一层branch block中)的值,这样从root -> branch -> leaf的时候才能准确定位到leaf block.
在提供答案前,首先给出几种不同的论点
1.不管建立在多少列上,branch block中只存储leading column信息
2. 如果建立在n个列上,branch block中存储n-1列的信息
3. branch block上存储所有列的信息.
这三种观点都有问题,首先观点一
如果这个索引的leading column的可选择性很差,例如status或者flag这样的列,distinct value很少
这时候如果索引建立在 (status, id)上,对于
select * from table where status=0 and id=12345这样的查询,range scan并不能准确定位到 leaf block
对于观点二,在n=2的时候显然也可以用上面的例子来推翻
对于观点三,是可以正确定位到leaf block,但是如果对于像
index(id,name) 其中name 假定name字段类型为varchar(1000),这样的索引效率也不好
事实上因为id列可选择性很好,一般不需要再存储name值到branch block中就可以区分左右的block
在branch block中存储的name列的值浪费了branch block的空间,
而我们知道单个branch block中能够存储值的多少直接影响了树的高度,而树的高度显然直接影响了index的效率
通过上面的分析,以上的三种观点都是错误的,那么oracle究竟如何来存储列信息才能既做到准确定位leaf block又不存储多余的值呢?
这里首先给出试验的结果,我没有找到官方文档或者其他的文章来解释这个结论,不过通过试验来看结论是很清楚的,而且也符合上面提到的两种考虑因素。
其实刚刚我们被限制住的原因是一直认为branch block中存储的列的个数是个常数,但事实上存储几个列是变化的。
这个值只需要区分其左右指针所指向的两个block的值就可以了,
更简单的说,当oracle从上到下走到这个branch block的时候,
通过这个值可以准确的知道向左走还是向右走,
举个例子,我们上面一开始提到的索引例子,
第一个是 index(status, id) , 如果左边block的最大值为(0,33),右边block的最小值为(0,35),
因为此时单纯从第一列不能区分两个block,这时就需要存储两列的信息
如果左边block最大值为(0,100),右边block最小值为(1,1)
因为此时从第一列就可以区分出两个block,所以只需要存储第一列的信息
这样对于
select * from table where status=0 and id=12345
查询,通过branch block中的值既可以知道“向左走,向右走”,准确定位leaf block
又可以避免不必要的浪费branch block空间,避免树高度不必要的增高
下面是试验的过程,直接copy以前自己发的邮件,懒得翻译了
We discussed the internal storage rule for composite index last time, but we didn’t get conclusion yet.
So I did a test for this.
SQL> create table test(n1 int,n2 int ,n3 int,v1 varchar2(2000),v2 varchar2(2000),v3 varchar2(2000));
Table created.
SQL> begin
2 for i in 1..1000 loop
3 insert into test values(0,i,i,rpad(’a',2000),rpad(’a',2000),rpad(’a',2000));
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
insert 1000 rows, the format is like this
0,1,1,xxxxxx,xxxxxxxxxx
0,2,2,xxxxxx,xxxxxxxxxx
0,3,3, xxxxxx,xxxxxxxxxx
……..
0,1000,1000, xxxxxx,xxxxxxxxxx
SQL> commit;
Commit complete.
create 7 indexes on this table, the naming rule is index_
_N (number) V (varchar)
SQL> create index index_2_nv on test(n1,v1);
Index created.
SQL> create index index_2_vn on test(v1,n1);
Index created.
SQL> create index index_3_nnv on test(n1,n2,v1);
Index created.
SQL> create index index_3_nvn on test(n1,v1,n2);
Index created.
SQL> create index index_4_nnnv on test(n1,n2,n3,v1);
Index created.
SQL> create index index_4_nnvn on test(n1,n2,v1,n3);
Index created.
SQL> create index index_5_nnnvv on test (n1,n2,n3,v1,v2);
Index created.
SQL> analyze table test compute statistics;
Table analyzed.
SQL> select index_name,PREFIX_LENGTH,BLEVEL,LEAF_BLOCKS from user_indexes
2 where lower(index_name) in (’index_2_nv’,'index_2_vn’,'index_3_nnv’,'index_3_nvn’,
3 ‘index_4_nnnv’,'index_4_nnvn’,'index_5_nnnvv’);
INDEX_NAME PREFIX_LENGTH BLEVEL LEAF_BLOCKS
—————————— ————- ———- ———–
INDEX_2_NV 5 334
INDEX_2_VN 5 334
INDEX_3_NNV 1 334
INDEX_3_NVN 5 334
INDEX_4_NNNV 1 334
INDEX_4_NNVN 1 334
INDEX_5_NNNVV 2 1000
7 rows selected.
You see, three indexes (INDEX_2_NV, INDEX_2_VN, INDEX_3_NVN) have level5. This means these indexes’ branch block contains varchar2000.
Then I dump these indexes’ root block to confirm this.
SQL> select segment_name,file_id,block_id from dba_extents where
2 lower(segment_name) in (’index_2_nv’,'index_2_vn’,'index_3_nnv’,'index_3_nvn’,
‘index_4_nnnv’,'index_4_nnvn’,'index_5_nnnvv’) and extent_id=0 order by segment_name 3 ;
SEGMENT_NAME FILE_ID BLOCK_ID
—————————— ———- ———-
INDEX_2_NV 9 16082
INDEX_2_VN 9 16097
INDEX_3_NNV 9 13587
INDEX_3_NVN 1 22053
INDEX_4_NNNV 1 32702
INDEX_4_NNVN 1 62230
INDEX_5_NNNVV 1 61697
7 rows selected.
SQL> @temp.sql
SQL> alter system dump datafile 9 block 16083;
System altered.
SQL> alter system dump datafile 9 block 16098;
System altered.
SQL> alter system dump datafile 9 block 13588;
System altered.
SQL> alter system dump datafile 1 block 22054;
System altered.
SQL> alter system dump datafile 1 block 32703;
System altered.
SQL> alter system dump datafile 1 block 62231;
System altered.
SQL> alter system dump datafile 1 block 61698;
System altered.
.
It’s weird. The index INDEX_2_NV and INDEX_2_VN only have 2 columns.But in the root block dump file, we can find col0,col1 and col2(maybesomething related to rowid, I guess).
I am not sure about what the third col is, but it’s clear that the number of columns in branch block is related about the data.
0,1,1,xxxxxx,xxxxxxxxxx
0,2,2,xxxxxx,xxxxxxxxxx
0,3,3, xxxxxx,xxxxxxxxxx
……..
0,1000,1000, xxxxxx,xxxxxxxxxx
The index INDEX_2_NV, INDEX_2_VN can’t distinguish the leaf blocksusing the prefix two columns, so it added the third column (unknown,maybe something related to rowid, I guess).
The indexes INDEX_3_NNV, INDEX_4_NNNV, INDEX_4_NNVN and INDEX_5_NNNVVcan distinguish the leaf blocks using the prefix two columns, so thebranch blocks only contain 2 columns.
The index INDEX_3_NVN can should use three columns to distinguish theleft/right leaf blocks, so it contains 3 columns (because the prefixtwo columns’ values are the same).
You can check the dump file xfan_ora_25936.trc for details.
So I guess that the number of columns stored in branch block is related to linked leaf blocks’ data.
The columns which stored in branch blocks need to distinguish the left/right linked leaf blocks.
If the rule for composite index is like I guessed, then the columnsstored in branch blocks maybe different in one index branch block!!
So I did another test to prove this:
SQL> create table test2(n1 int,n2 int,n3 int,v1 varchar2(2000),v2 varchar2(2000));
Table created.
SQL> create index test_idx on test2(n1,n2,n3,v1,v2);
Index created.
SQL> begin
2 for i in 1..1000 loop
insert into test2 values(0,0,i,rpad(’a',2000),rpad(’a',2000));
end loop;
end;
/ 3 4 5 6
PL/SQL procedure successfully completed.
Insert first 1000 rows like this:
0, 0, 1, xxxxx,xxxxxx
0, 0, 2, xxxxx,xxxxxx
0, 0, 3, xxxxx,xxxxxx
……
0, 0, 1000, xxxxx,xxxxxx
SQL> SQL>
SQL> begin
2 for i in 1001..2000 loop
insert into test2 values(0,i,i,rpad(’a',2000),rpad(’a',2000));
end loop;
end;
/ 3 4 5 6
Then insert other 1000 rows like this:
0,1,1,xxxx,xxxx
0,2,2,xxxx,xxxx
0,3,3,xxxx,xxxx
…….
0,1000,1000,xxxx,xxxx
Then I did treedump and branch block dump.
Here is a snippet of the branch block dump:
row#454[2145] dba: 4218395=0×405e1b
col 0; len 1; (1): 80
col 1; len 1; (1): 80
col 2; len 3; (3): c2 0a 64
col 3; TERM
row#455[2133] dba: 4218396=0×405e1c
col 0; len 1; (1): 80
col 1; len 1; (1): 80
col 2; len 2; (2): c2 0b
col 3; TERM
row#456[2124] dba: 4218397=0×405e1d
col 0; len 1; (1): 80
col 1; len 1; (1): c2
col 2; TERM
row#457[2113] dba: 4218398=0×405e1e
col 0; len 1; (1): 80
col 1; len 3; (3): c2 0b 03
col 2; TERM
row#458[2102] dba: 4218399=0×405e1f
col 0; len 1; (1): 80
col 1; len 3; (3): c2 0b 04
col 2; TERM
You see, the numbers of columns changed in one branch block!!
The attachment index.trc is the dump file
So the conclusion is that the number of columns stored in branch block is related to linked leaf blocks’ data.
The branch block will store as less columns as possible to distinguish the left/right leaf blocks it linked
发表评论
-
expdp通过dblink来导入
2011-12-14 15:01 1798create.sql: spo create.log rem ... -
Library cache内部机制详解
2011-12-14 14:55 920Library cache内部机制详解 http://www ... -
Oracle的10046事件
2011-12-14 14:53 2105Oracle的10046事件,可以跟踪应用程序所执行的SQL语 ... -
REDO LOG MEMBER STATUS 和 REDO LOG GROUP STATUS
2011-12-14 14:51 935V$LOG 中列出的是REDO LOG GROUP STA ... -
oracle的exp/imp使用方法学习(转)
2011-08-30 08:54 971exp/imp两个命令可以说是oracle中最常用的命令了 ... -
oracle几个awr报告
2011-08-09 14:25 903工作中,碰到的数据库慢的几个awr报告 -
Oracle Profile 使用详解
2011-06-21 14:41 978一、目的: Oracle系统中的profile可以用来对 ... -
ORA-27013
2011-04-13 14:25 1521很新的一个bug,看下你的 memory_target是不是& ... -
ACLE表连接方式分析及常见用法
2011-03-23 09:14 1118摘要: 针对在数据仓库 ... -
ORACLE 外部表应用
2011-03-09 14:58 1075SQL> create or replace direc ... -
How to convert a 32-bit database to 64-bit database on Linux
2011-02-18 14:09 1222How to convert a 32-bit databas ... -
expdp impdp 数据库导入导出命令详解
2011-02-16 09:10 1962一、创建逻辑目录,该命令不会在操作系统创建真正的目录,最 ... -
Oracle手工解/锁表
2011-01-25 14:15 2515手工锁表:lock table tbl_t1 in row ... -
oracle动态性能视图
2011-01-22 10:47 866Oracle动态性能视图个人整理 -
RBO规则介绍
2011-01-17 16:45 1095•无条件使用索引•使用内置的优先级别决定访问路径•比较难以 ... -
关于排序、sort_area_size、临时表空间
2011-01-13 15:30 1127简单陈述一下:针对每 ... -
创建索引ORACLE 需要做的工作
2011-01-13 14:53 1327一. 先来看一下创建索引要做哪些操作:1. 把inde ... -
表之间的连接
2011-01-13 10:42 804Join是一种试图将两个表结合在一起的谓词,一次只能连接2 ... -
重建索引的条件
2011-01-12 16:43 962如果索引存在碎片,那每个索引数据块上的索引数据就更少,会导致我 ... -
TKPROF使用学习
2011-01-10 17:38 734Tkprof工具可用来格式化sql trace产生的文件, ...
相关推荐
- **复合索引**:对于多列查询,可以创建复合索引,将多个列组合在一起,提高查询效率。索引顺序应根据查询条件的频率和选择性进行优化。 - **覆盖索引(Covering Index)**:如果索引包含了查询所需的所有列,那么...
这种模型通常包括一个较小的分支目标缓冲器(Branch Target Buffer, BTB)以及一个较大的模式历史表(Pattern History Table, PHT),用于存储分支执行历史和模式历史。 2. **九种变体**:通过对基础模型进行不同...
标题“非唯一索引分支和叶块结构”指的是数据库管理系统中的数据存储结构,特别是与B树(B-tree)或B+树(B+tree)相关的概念。这些数据结构在数据库索引中扮演着核心角色,特别是在关系型数据库系统中,如MySQL、...
这将在当前分支的基础上创建一个名为`feature/new-feature`的新分支,并立即检出它。 4. **搜索分支** 如果你的分支很多,可以使用`-s`或`--search`选项进行模糊搜索,输入部分分支名来筛选: ```bash select...
Branch类通常有一个创建分支的方法,例如`createNewBranch(String branchName)`,这个方法会根据给定的名字创建一个新的分支。 2. **切换分支**:在开发过程中,开发者可能需要在不同分支间切换。`switchToBranch...
在Intel处理器架构中,"Intel Branch Trace Store"(BTS)是一种硬件辅助的性能监控功能,它用于记录程序执行过程中的分支历史信息。这个技术主要目的是为了帮助软件开发者和性能分析人员理解程序的控制流,优化代码...
1. **MIPS 分支指令**:MIPS提供了几种不同的分支指令,如`beq`(Branch if Equal)、`bne`(Branch if Not Equal)、`blez`(Branch if Less Than or Equal to Zero)、`bgez`(Branch if Greater Than or Equal to...
5. **SDX整合**:与NetScaler SDX(Software Defined Exchange)的整合,使得Branch Repeater能够在一个物理平台上虚拟化运行,提高了资源利用率和管理效率。 6. **经济实惠**:Branch Repeater VPX Express版本...
相比之下,《Branch Prediction For Free》这篇文章介绍了一种基于程序本身的静态分支预测方法(program-based branch prediction),这种方法无需额外的运行时信息即可实现有效的分支预测。 #### 二、文章摘要解读...
它基于二叉树原理,由分支块(branch block)和叶块(leaf block)构成,能够高效地处理高基数数据列的检索。所谓高基数,指的是该列拥有大量不同的值。B\*Tree索引特别适用于当所需检索的行数占总行数比例较低的情况,...
B*Tree索引是最常用的索引类型之一,其结构基于二叉树,由分支块(branch block)和叶块(leaf block)构成。分支块用于存储指向其他分支块或叶块的指针,以及用于导航的键值;叶块则直接存储索引键值及其对应的行标识符...
4. **使用复合索引**:当查询条件涉及多个列时,可以考虑创建复合索引以提高查询效率。 #### 六、案例分析 从提供的部分数据内容来看,“Rootblock”、“Branch blocks”、“Leaf blocks”分别对应于B树索引的根...
在Spark 2.3中,主要包含以下几个关键组件: 1. Spark Core:这是Spark的基础模块,负责任务调度、内存管理、故障恢复、与存储系统交互等功能。Spark Core提供了一种通用的计算模型,使得其他模块如Spark SQL、...
在这个任务中,学生需要完成以下几个关键知识点: 1. **视图的创建**: 视图是数据库中的虚拟表,它根据用户定义的SQL查询结果动态生成。在本例中,创建了一个名为`branch_detail`的视图,用来显示每个支行的存款...
CDDFuse(Correlation-Driven Dual-Branch Feature Decomposition)是一种用于多模态图像融合的深度学习方法,主要针对如何有效建模跨模态特征并分解出特定模态和共享模态特征的挑战。论文的目的是在融合图像中保留...
关于标题“binary matrix with maximum branch number”和描述“Construction method for binary matrix with maximum branch number”的知识点,主要涉及到二进制矩阵及其分支数概念以及构造具有最大分支数的二进制...
每当项目达到一个稳定版本,如1.0、2.0等,开发者会在trunk或branch上创建一个tag,以记录这个版本的所有代码。tag不应该被修改,它是项目历史的一个固定点,可以随时回溯查阅。 4. **Merge**:Merge是将代码从一个...
社交讨论平台Branch致力于重构信息分享规则,通过其独特的方式促进高质量的对话和深度交流。该平台自2021年3月上线以来,已经逐步发展并开放给所有用户。Branch的核心理念是创造一个像围坐在同一张桌子旁进行深入...
在这个列上创建了一个B树索引。 - **数据块大小**:默认情况下,Oracle的数据块大小为8KB。 - **PCTFREE**:默认值为10%,这意味着每个数据块中只有90%的空间可以用于存储数据。实际上,这个值会进一步减少至大约87...
### 在SVN中使用分支/Branch进行版本控制 #### 1. 名词缩略语释义 在探讨如何在Subversion (SVN) 中利用分支进行版本控制之前,我们首先需要理解一些基本术语。 - **PCM** (Project Configuration Manager): 项目...