达梦索引组织表和堆表

达梦数据库默认创建的是索引组织表,‌而Oracle数据库默认创建的是堆表。‌这两种表类型的区别主要体现在数据存储和组织方式上:

  1. 索引组织表(‌Index Organized Table, IOT):‌
    索引组织表‌有且仅有一个聚簇索引键。索引组织表也称“普通表”,数据都是以B树形式存放的,ROWID都是逻辑的ROWID,即从1一直增长下去。在并发情况下,每次插入过程中都需要逻辑生成ROWID,这样影响了插入数据的效率;对于每一条数据都需要存储ROWID值,也会花费较大的存储空间。
    索引组织表数据按照聚簇索引键排序(‌数据是有序的,‌插入有序)。
  2. 堆表(Heap Table):
    堆表的数据是以挂链形式存储的,一般情况下,支持最多128个链表,一个链表在物理上就是一个段,堆表采用的是物理rowid,在插入过程中,rowid在事先已确定,并保证其唯一性,所以可以并发插入,插入效率很高,且由于rowid是即时生成,无需保存在物理磁盘上,也节省了空间。
    ‌堆表的数据存储没有特定的顺序,‌是随机存储的。
    为支持并发插入,扁平B树可以支持最多128个数据页链表(最多64个并发分支和最多64个非并发分支),在B树的控制页中记录了所有链表的首、尾页地址。

NOBRANCH:如果指定为 NOBRANCH,则创建的表为堆表,并发分支个数为0,非并发分支个数为1;
BRANCH(N,M):如果为该形式,则创建的表为堆表,并发分支个数为N,非并发个数为M;
BRANCH N:指定创建的表为堆表,并发分支个数为 N,非并发分支个数为1;
CLUSTERBTR:创建的表为非堆表,即普通B树表。

用户可以在配置文件中,添加LIST_TABLE参数:

  1. 如果LIST_TABLE = 1,则在未显式指定表是否为堆表或非堆表时,默认情况下创建的表为堆表;
  2. 如果LIST_TABLE = 0,则在未显式指定表是否为堆表或非堆表时,默认情况下创建的表为普通表形式。

1. 创建表

创建索引组织表

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

创建堆表

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

通过DBA_TABLES视图区分索引组织表和堆表

SELECT TABLE_NAME, IOT_TYPE 
  FROM DBA_TABLES 
 WHERE TABLE_NAME IN ('CLUSTER_T1',
                      'HEAP_T1');

在这里插入图片描述




通过索引类型区分索引组织表和堆表,可以看到这两种类型的表都会创建一个默认索引

   SELECT D1.TABLE_NAME,
          D1.INDEX_NAME,
          D1.INDEX_TYPE,
          S2.XTYPE
     FROM SYS.DBA_INDEXES D1
LEFT JOIN SYS.SYSOBJECTS S1
       ON D1.INDEX_NAME=S1.NAME
      AND S1.SCHID=(SELECT A.ID FROM SYSOBJECTS A WHERE A.TYPE$ ='SCH' AND A.NAME='SYSDBA')
LEFT JOIN SYS.SYSINDEXES S2
       ON S1.ID=S2.ID
    WHERE D1.TABLE_NAME IN ('CLUSTER_T1',
                            'HEAP_T1');

在这里插入图片描述




索引组织表只能创建一个聚集索引。手动再添加聚集索引,则会覆盖默认创建的聚集索引。
两张表添加主键索引,均为二级索引。

create cluster  index "SYSDBA"."IDXC_CLUSTER_T1_C1" on "SYSDBA"."CLUSTER_T1"("C1");
alter table "SYSDBA"."CLUSTER_T1" add primary key("C1");
alter table "SYSDBA"."HEAP_T1" add primary key("C1");

在这里插入图片描述




2. 测试

插入数据

[执行语句1]:
TRUNCATE TABLE CLUSTER_T1;
执行成功, 执行耗时80毫秒. 执行号:33240
影响了0条记录

[执行语句2]:
TRUNCATE TABLE HEAP_T1;
执行成功, 执行耗时21毫秒. 执行号:33241
影响了0条记录

[执行语句3]:
INSERT INTO cluster_t1 SELECT LEVEL C1,level%100 C2,'test','test' FROM DUAL CONNECT BY LEVEL<=5000000;
执行成功, 执行耗时1分 28933毫秒. 执行号:33242
影响了5,000,000条记录

[执行语句4]:
INSERT INTO    HEAP_T1 SELECT LEVEL C1,level%100 C2,'test','test' FROM DUAL CONNECT BY LEVEL<=5000000;
执行成功, 执行耗时28秒 235毫秒. 执行号:33243
影响了5,000,000条记录

创建的HEAP_T2表,有并发分支2个,非并发分支4个

[执行语句1]:
CREATE TABLE HEAP_T2(C1 INT ,C2 INT,C3 VARCHAR(20) ,C4 VARCHAR(20)) STORAGE(BRANCH(2,4));
执行成功, 执行耗时8毫秒. 执行号:33247
影响了0条记录

[执行语句2]:
INSERT INTO HEAP_T2 SELECT LEVEL C1,level%100 C2,'test','test' FROM DUAL CONNECT BY LEVEL<=5000000;
执行成功, 执行耗时9秒 170毫秒. 执行号:33248
影响了5,000,000条记录

对比数据占用空间

select SEGMENT_NAME,BYTES/1024/1024 as SIZE_M from SYS.DBA_SEGMENTS where SEGMENT_NAME in ('CLUSTER_T1', 'HEAP_T1', 'HEAP_T2');

在这里插入图片描述




3. 总结

  1. 对于大数据量的存量数据表,使用索引组织表,占用空间更小;
  2. 对于经常有大批量的数据插入场景,使用堆表,插入速度更快,效率更高;
  3. 对于小数据量的表,使用索引组织表,虽然占用空间更多但可以接受;
  4. 堆表增加并发分支和非并发分支,效率会更高。



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

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值