签到成功

知道了

CNDBA社区CNDBA社区

DM 达梦数据库 表的 行计数器(COUNTER)属性

2019-11-28 14:24 6483 0 原创 DM 达梦
作者: dave

1 表行计数器 说明

默认情况下,DM 达梦数据库count() 是秒回结果的,不受表中实际行数的影响,执行select count() 都能立即返回正确的结果。因为达梦数据库的count(*)操作不需要执行全表扫描,直接读取表行计数器的结果。

这个表行计数器实际上是表的一个存储属性,在创建表时可以指定是否启用表行计数器。默认为启动,可以配置为如下2个值:http://www.cndba.cn/cndba/dave/article/3829http://www.cndba.cn/cndba/dave/article/3829

WITH COUNTER:默认值,在表上维护当前表内的行数;
WITHOUT COUNTER:表上只维护一个非实时的大概的行数;

如果表启用了WITH COUNTER 属性, SELECT COUNT(*)时服务器直接取行数返回即可,可以快速响应;
如果表是 WITHOUT COUNTER 属性,服务器需要先扫描 B 树获取行数返回后才能响应。http://www.cndba.cn/cndba/dave/article/3829http://www.cndba.cn/cndba/dave/article/3829

COUNTER 属性可以通过alter table语句直接进行修改。

2 测试

2.1 创建默认启用counter的表cndba

[dave@www.cndba.cn ~]$ disql SYSDBA/SYSDBA

服务器[LOCALHOST:5236]:处于普通打开状态
登录使用时间: 12.679(毫秒)
disql V8
SQL> create table cndba(id int,website varchar(50));
操作已执行
已用时间: 9.588(毫秒). 执行号:3281.
SQL> insert into cndba values(1,'https://www.cndba.cn/dave');
影响行数 1

已用时间: 1.908(毫秒). 执行号:3282.
SQL> commit;
操作已执行
已用时间: 1.376(毫秒). 执行号:3283.
SQL>

查看此时的执行计划http://www.cndba.cn/cndba/dave/article/3829

SQL> explain select count(*) from cndba;

1   #NSET2: [0, 1, 0] 
2     #PRJT2: [0, 1, 0]; exp_num(1), is_atom(FALSE) 
3       #FAGR2: [0, 1, 0]; sfun_num(1), 

已用时间: 29.509(毫秒). 执行号:0.
SQL>

2.2 创建没有启用counter的表cndba2

SQL> create table cndba2(id int,website varchar(50)) storage(without counter);        
操作已执行
已用时间: 5.633(毫秒). 执行号:3284.
SQL>  insert into cndba2 values(2,'https://www.cndba.cn/dave');
影响行数 1

已用时间: 2.107(毫秒). 执行号:3285.
SQL> commit;
操作已执行
已用时间: 1.856(毫秒). 执行号:3286.


SQL> explain select count(*) from cndba2;

1   #NSET2: [0, 1, 0] 
2     #PRJT2: [0, 1, 0]; exp_num(1), is_atom(FALSE) 
3       #AAGR2: [0, 1, 0]; grp_num(0), sfun_num(1) slave_empty(0)
4         #CSCN2: [0, 1, 0]; INDEX33555492(CNDBA2)

已用时间: 1.307(毫秒). 执行号:0.
SQL>

2.3 对比

2.3.1 查看表的定义语句

启用表行计数器:

[dave@www.cndba.cn Code]# drz getddl table cndba SYSDBA

*****************DDL SQL******************

CREATE TABLE "SYSDBA"."CNDBA"
(
"ID" INT,
"WEBSITE" VARCHAR(50)) STORAGE(ON "MAIN", CLUSTERBTR) ;

[dave@www.cndba.cn Code]#

未启用表行计数器:

[dave@www.cndba.cn Code]# drz getddl table cndba SYSDBA
*****************DDL SQL******************

CREATE TABLE "SYSDBA"."CNDBA2"
(
"ID" INT,
"WEBSITE" VARCHAR(50)) STORAGE(ON "MAIN", CLUSTERBTR, WITHOUT COUNTER) ;

[dave@www.cndba.cn Code]#

2.3.2 执行计划的操作符

启用counter:

2     #PRJT2: [0, 1, 0]; exp_num(1), is_atom(FALSE) 
3       #FAGR2: [0, 1, 0]; sfun_num(1),

FAGR2 表示:快速聚集,如果没有 where 条件,且取 count(*), 或者基于索引的 MAX/MIN 值,则可以快速取得集函数的值

http://www.cndba.cn/cndba/dave/article/3829

未启用counter:http://www.cndba.cn/cndba/dave/article/3829

2     #PRJT2: [0, 1, 0]; exp_num(1), is_atom(FALSE) 
3       #AAGR2: [0, 1, 0]; grp_num(0), sfun_num(1) slave_empty(0)
4         #CSCN2: [0, 1, 0]; INDEX33555492(CNDBA2)

AAGR2表示:简单聚集
CSCN2表示:聚集索引扫描

2.4 Counter 状态切换

将cndba 改成不启用counter:http://www.cndba.cn/cndba/dave/article/3829

SQL>  alter table cndba without counter;
操作已执行
已用时间: 9.653(毫秒). 执行号:3291.
SQL> 

[dave@www.cndba.cn Code]# drz getddl table cndba SYSDBA

*****************DDL SQL******************

CREATE TABLE "SYSDBA"."CNDBA"
(
"ID" INT,
"WEBSITE" VARCHAR(50)) STORAGE(ON "MAIN", CLUSTERBTR, WITHOUT COUNTER) ;

将cndba2 改成启用counter:

SQL> alter table cndba2 with counter;
操作已执行
已用时间: 5.636(毫秒). 执行号:3294.
SQL> 

[dave@www.cndba.cn Code]# drz getddl table cndba2 SYSDBA

*****************DDL SQL******************

CREATE TABLE "SYSDBA"."CNDBA2"
(
"ID" INT,
"WEBSITE" VARCHAR(50)) STORAGE(ON "MAIN", CLUSTERBTR) ;

2.5 Count(*) 时间对比

2.5.1 启用counter

SQL> create table t1 as select * from sysobjects;
操作已执行
已用时间: 11.657(毫秒). 执行号:3297.
SQL> insert into t1 select * from t1;
影响行数 1399

已用时间: 28.383(毫秒). 执行号:3298.
SQL> insert into t1 select * from t1;
影响行数 2798

已用时间: 14.120(毫秒). 执行号:3299.
SQL>  insert into t1 select * from t1;
影响行数 5596

已用时间: 21.753(毫秒). 执行号:3300.
SQL> commit;
操作已执行
已用时间: 1.950(毫秒). 执行号:3301.
SQL> select count(*) from t1;

行号     COUNT(*)            
---------- --------------------
1          11192

已用时间: 1.902(毫秒). 执行号:3302.

查询11192 花费1.902 毫秒。

http://www.cndba.cn/cndba/dave/article/3829

2.5.2 未启用counter

SQL> create table t2 as select * from sysobjects where 1=2;
操作已执行
已用时间: 7.219(毫秒). 执行号:3303.
SQL> alter table t2 without counter;
操作已执行
已用时间: 7.715(毫秒). 执行号:3304.
SQL> insert into t2 select * from t1;
影响行数 11192

已用时间: 31.559(毫秒). 执行号:3305.
SQL> commit;
操作已执行
已用时间: 1.500(毫秒). 执行号:3306.
SQL> select count(*) from t2;

行号     COUNT(*)            
---------- --------------------
1          11192

已用时间: 2.608(毫秒). 执行号:3307.
SQL>

查询11192 花费2.608 毫秒。

我们这里仅仅是1w多条数据,如果是上千万级别的记录数,那么时间差距就会更明显一些。 http://www.cndba.cn/cndba/dave/article/3829

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2261
    原创
  • 3
    翻译
  • 578
    转载
  • 191
    评论
  • 访问:8028227次
  • 积分:4346
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ