----------------------------------------------------------------------------
---- 本文为andkylee个人原创,请在尊重作者劳动成果的前提下进行转载;
---- 转载务必注明原始出处 : http://blog.csdn.net/andkylee
---- 关键字: 索引 存储结构 分析 非聚簇 index storage non-clustered
----------------------------------------------------------------------------
迄今已分析出来了sybase中索引(indid>1)的物理存储结构。
索引结构是B-Tree类型的。最顶部叫做根(root),最底层称为叶子(leaf)。一个表可能建有好几个非聚簇索引,这时indid依次为2,3,。。。递增。
对于一个索引,比如indid=2的那个。索引树状结构是分层次的,在sybase数据存储中用level表示,根部级别最高,叶子的级别最低。叶子(leaf)的级别level为0,往上索引层level为1,再往上位2,。。。最后到达顶部root级别为(N-1,N为所有的层次数)。
不管APL还是DOL表,索引的每层(level)上的页面都是前后链接起来的,这一点有点像APL表中的数据页面上的前、后页链(data page link)。
以下简要演示分析索引结构的过程。
1.
设定成在终端显示dbcc结果信息。
2.
查看syspartitions表的信息
表PartitionTestTable是在其上的id列建了4个分区的分区表,它有2个索引。idx_PartitionTestTable_id对id列索引,idx_PartitionTestTable_name对name列索引。
我们就分析idx_PartitionTestTable_id这个索引吧。通过syspartitions表我们可以得到四个比较有用的datoampage,indoampage, firstpage ,rootpage。分别表示数据对象分配页的页号,索引对象分配页的页号,
索引叶子层上的第一页,索引根部的页号。(堆表信息中的firstpage,rootpage意思有些不同。分别表示:数据页的第一个、最后一页。)
有:datoampage=0,indoampage=62465,firstpage= 67256,rootpage=66248.
对于indoampage索引对象分配页,可以这么查看。(PartitionTestTable的objid为: 1223672376)
dbcc listoam(4,1223672376,2)
3.可以看出索引idx_PartitionTestTable_id在14个对象分配页allocation page上的分配情况如下:
(此处,暂时不解释以上结果中的情况!)
4.现在回到索引上,先从根部分析。rootpage=66248。
查看66248页上的16进制数据。
dbcc page(4,66248,1)
此时,可以看出索引根部的级别level为2。 也就是说索引还有中间层level=1和叶子层level=0.
看第二行数据,
Offset 47 - row length=15 # varlen cols=0 Child page ID=65823
2828702F ( 0): 00be8301 00aff000 0041001f 010100 .........A.....
Row-Offset table for variable-length columns:
[<varcol number>, <offset from start of the row>, <varcol length>]
它的子页面号是:65823。
再来查看65823的页面数据。
此页面65823是索引的中间层level=1.看第一行的数据。
Offset 32 - row length=15 # varlen cols=0 Child page ID=65822
28287020 ( 0): 00be8301 00aff000 0041001e 010100 .........A.....
Row-Offset table for variable-length columns:
[<varcol number>, <offset from start of the row>, <varcol length>]
页面:66248上的第二行就是指向该行。
继续查看它的子页面上的数据,65822。
还是分析页面上的第一行。索引叶子层直接指向了数据页面,某一页面上的某一行。
Offset 32 - row length=11 # varlen cols=0 Data page RID=(61615, 65)
28287020 ( 0): 00be8301 00aff000 004100 .........A.
Row-Offset table for variable-length columns:
[<varcol number>, <offset from start of the row>, <varcol length>]
继续往下,dbcc page(4,61615,1)找到第65行数据。
Offset 1072 - row ID=65 row length=16 # varlen cols=1
28287430 ( 0): 0141be83 0100 1000 7a68616e 67020d08 .A......zhang...
28287440 ( 16):
Row-Offset table for variable-length columns:
[<varcol number>, <offset from start of the row>, <varcol length>]
[1, 8, 5]
可以看出00be8301 00 aff000 004100中的be8301 00 和0141be83 01001000 7a68616e 67020d08中的
be83 0100 是一致的。也就是说索引中间层level=1是指向叶子层上的第一页。并且包含索引键的数据99262。
从16进制数据中分析出来,页61615第65行的数据为:id=99262,name='zhang'。
暂时就分析这么多。可能有些地方说的不太明白。见谅!