• 欢迎光临~

达梦索引组织表和堆表

开发技术 开发技术 2022-08-05 次浏览

达梦数据库对于行存数据表支持索引组织表和堆表两种形式,两者的都有rowid列,用于在执行其他索引时快速定位数据(一般业务查询不会以rowid列为查询条件),两种表的区别在于:

索引组织表:在达梦数据库中的默认行表组织类型,默认以B数形式存放数据,ROWID列是逻辑值 ,从1开始一直增长,在数据的插入时默认会插入ROWID列值,所以插入速度会受此列影响而变慢,同时也会占用更多的存储空间。索引组织表在创建时如果未显式的创建一个聚集索引,则默认的会创建一个聚集索引,这个索引由达梦数据库自动维护,手动再添加聚集索引,则会覆盖默认创建的聚集索引。索引组织表只能创建一个聚集索引。

手动创建一个索引组织表,对以上信息进行论证:

创建语句:

CREATE TABLE cluster_t1(C1 INT,C2 int,C3 VARCHAR(20) ,C4 VARCHAR(20));

查看聚集索引:

达梦索引组织表和堆表

可以看到,默认的创建一个随机名称的聚集索引,此时再手工创建一个聚集索引,则会覆盖默认创建的聚集索引:

达梦索引组织表和堆表

此时,创建了一个名称为"abc"的聚集索引。

插入数据验证rowid的值:

达梦索引组织表和堆表

插入1000行数据,可以看到此时索引组织表的rowid是从1开始一直增长的数字。

堆组织表:在达梦数据库中,堆组织表以扁平B数进行数据行的存储,数据页由链表形式进行表页数据的组织,最多支持128个数据页链表,最多64个并发分支和64个非并发分支,当然分支越多,占用的空间也就越大。堆组织表同样有ROWID列,与索引组织表不同的是,堆组织表的ROWID是物理ROWID,由文件号、页号、页内偏移三个数字共同组成,不需要额外的空间来存在此值,在达梦数据库,如果需要创建堆组织表,有两种方式,一种是在dm.ini文件中配置LIST_TABLE=1,或者在存储选项中,以关键字NOBRANCH,BRANCH显式的进行创建,其中NOBRANCH创建的堆表并发分支个数为0,非并发分支个数为1,BRANCH如果指定非并发个数,则以具体值来定义非并发个数,如果未指定,则为0。堆表在创建时,默认的也会创建一个索引,类型为"FLAT"

手动创建一个堆表,对以上信息进行论证:

创建语句为:

CREATE TABLE heap_t1(C1 INT ,C2 int,C3 VARCHAR(20) ,C4 VARCHAR(20)) STORAGE(NOBRANCH); --STORAGE(BRANCH(2,4))

查看索引情况:

达梦索引组织表和堆表

默认的也创建了一个随机名字的索引。

插入数据验证ROWID的值:

达梦索引组织表和堆表

插入1000行数据,可以看到此时的rowid值不是索引组织表中的1开始一直增长的值,代替的是达梦的数据页相关信息。

以上对比了索引组织表的堆组织表的基础信息,接下来对比一下上面提到的空间占用情况以及两种表的性能情况进行验证,在创建堆组织表的情况下,使用 STORAGE(NOBRANCH)、STORAGE(BRANCH(n,m))两种情况验证插入速度,即增加并发分支和非并发分支的情况下验证。

重新创建两种行存形式的表,查看表大小:

达梦索引组织表和堆表

以上为未加堆组织表未加分支的情况下表大小

达梦索引组织表和堆表

在加了32并发分支和32非并发分支的情况下,堆表初始大小是索引组织表大小的2.5倍,经过多次验证,随着并发分支和非并发分支数量的不同,堆表的大小一直都有变化,数值越大,占用初始占用的空间也越大。

空表以及堆表未加分支情况下,索引组织表的大小约为堆组织表的2倍大小,为验证实际占用空间,每个表插入相同值的500万行记录,再查看大小:

达梦索引组织表和堆表

 

清除掉数据,插入1万行数据,再查看大小:

达梦索引组织表和堆表

通过以上的验证过程,可以证明,堆表虽然未使用逻辑rowid占用更多的空间,但是只有在数据量较少的情况下,总体占用空间才会小,对于大数据量的数据存储,占用空间还是比索引组织表占用空间大,数据量越大,占用空间也就越多,在插入近10万行数据时,占用空间持平。

接下来验证一下插入数据和查询数据时的性能,分为数据量50万行和500万行两种情况下测试,在进行测试的同时,添加主键索引,测试语句为以下语句:

CREATE TABLE heap_t1(C1 INT ,C2 int,C3 VARCHAR(20) ,C4 VARCHAR(20)) STORAGE(NOBRANCH);

alter table SYSDBA."heap_t1" add PRIMARY KEY(C1);

CREATE TABLE cluster_t1(C1 INT,C2 int,C3 VARCHAR(20) ,C4 VARCHAR(20));

alter table SYSDBA."cluster_t1" add PRIMARY KEY(C1);

INSERT INTO cluster_t1 SELECT LEVEL C1,level%100 C2,'test','test' FROM DUAL CONNECT BY LEVEL<=500000; --过程中需修改数量

commit;

 

INSERT INTO heap_t1 SELECT LEVEL C1,level%100 C2,'test','test' FROM DUAL CONNECT BY LEVEL<=500000; --过程中需修改数量

commit;

50万行数据插入测试:

索引组织表结果

达梦索引组织表和堆表

堆组织表结果

达梦索引组织表和堆表

两者插入数据相差不大。

500万行数据插入测试:

索引组织表结果

达梦索引组织表和堆表

堆组织表结果:

达梦索引组织表和堆表

大批量的数据插入时,堆表的实际执行时长差不多比索引组织表多了近30%的时长。

对于针对单表的查询操作,不管是500万行还是50万行,或者是两种数量级的全表扫描、索引二级扫描等,基本时长和执行计划都一致,这里不再贴图。

总结说明

经过以上操作验证,对比两种表行数据的组织方式,在达梦数据库中,对两种表的使用可以遵循以下原则:

1.对于大数据量的存量数据表,使用索引组织表,占用空间更小;

2.对于经常有大批量的数据插入场景,使用索引组织表,插入速度更快,效率更高;

3.对于小表数量不多,使用索引组织表,虽然索引组织表在小数据量时占用空间更多,但是小表数据少的情况下,可以考虑使用。

4.对于小表数据特别多,空间有限的场景下,可以考虑使用堆表,占用空间小。

 

达梦社区:https://eco.dameng.com

程序员灯塔
转载请注明原文链接:达梦索引组织表和堆表
喜欢 (0)