注册
DM表的行计数器(COUNTER)属性
技术分享/ 文章详情 /

DM表的行计数器(COUNTER)属性

Mercy 2025/09/30 18 0 0

表行计数器说明

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

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

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

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

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

测试counter

01

创建默认启用counter的表cndba

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

服务器[LOCALHOST:5236]:处于普通打开状态

登录使用时间:12.679(毫秒)

disqlV8

SQL> create table cndba( id int,website varchar( 50)) ;

操作已执行

已用时间:9.588(毫秒).执行号:3281.

SQL> insert intocndba values( 1, ‘https://www.cndba.cn/dave’) ;

影响行数1

已用时间:1.908(毫秒).执行号:3282.

SQL>commit;

操作已执行

已用时间:1.376(毫秒).执行号:3283.

查看此时的执行计

SQL> explain selectcount( *) fromcndba ;

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.

02

创建没有启用counter的表cndba2

SQL> create table cndba2( id int,website varchar( 50)) storage( without counter) ;

操作已执行

已用时间:5.633(毫秒).执行号:3284.

SQL> insert intocndba2 values( 2, ‘https://www.cndba.cn/dave’) ;

影响行数1

已用时间:2.107(毫秒).执行号:3285.

SQL>commit;

操作已执行

已用时间:1.856(毫秒).执行号:3286.

SQL> explain selectcount( *) fromcndba2 ;

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)

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

03

对比

① 查看表的定义语句

启用表行计数器:

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

DDLSQL*

CREATE TABLE “SYSDBA”.“CNDBA”

(

"ID"INT,

“WEBSITE” VARCHAR(50)) STORAGE(ON “MAIN”, CLUSTERBTR) ;

未启用表行计数器:

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

DDLSQL*

CREATE TABLE “SYSDBA”.“CNDBA2”

(

"ID"INT,

“WEBSITE” VARCHAR(50)) STORAGE(ON “MAIN”, CLUSTERBTR, WITHOUT COUNTER)

;

②执行计划的操作符

启用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 值,则可以快速取得集函数的值

未启用counter:

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)

AAGR2表示:简单聚集

CSCN2表示:聚集索引扫描

04

Counter 状态切换

将cndba改成不启用counter:

SQL>alter table cndba without counter;

操作已执行

已用时间:9.653(毫秒).执行号:3291.

SQL>[dave@www.cndba.cnCode] # drz getddl table cndba SYSDBA

DDLSQL*

CREATE TABLE “SYSDBA”.“CNDBA”

(

"ID"INT,

“WEBSITE” VARCHAR(50)) STORAGE(ON “MAIN”, CLUSTERBTR, WITHOUT COUNTER) ;

将cndba2改成启用counter:

SQL>alter table cndba2 withcounter;

操作已执行

已用时间:5.636(毫秒).执行号:3294.

SQL>[dave@www.cndba.cnCode] # drz getddl table cndba2 SYSDBA

DDLSQL*

CREATE TABLE “SYSDBA”.“CNDBA2”

(

"ID"INT,

“WEBSITE” VARCHAR(50)) STORAGE(ON “MAIN”, CLUSTERBTR) ;

05

Count(*) 时间对比

①启用counter

SQL>create table t1 asselect* fromsysobjects;

操作已执行

已用时间:11.657(毫秒).执行号:3297.

SQL>insert intot1 select* fromt1;

影响行数1399

已用时间:28.383(毫秒).执行号:3298.

SQL>insert intot1 select* fromt1;

影响行数2798

已用时间:14.120(毫秒).执行号:3299.

SQL> insert intot1 select* fromt1;

影响行数5596

已用时间:21.753(毫秒).执行号:3300.

SQL>commit;

操作已执行

已用时间:1.950(毫秒).执行号:3301.

SQL> selectcount( *) fromt1 ;

行号 COUNT(*)


1 11192

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

查询11192花费1.902 毫秒 。

②未启用counter

SQL>create table t2 asselect* fromsysobjects where1= 2;

操作已执行

已用时间:7.219(毫秒).执行号:3303.

SQL>alter table t2 without counter;

操作已执行

已用时间:7.715(毫秒).执行号:3304.

SQL>insert intot2 select* fromt1;

影响行数11192

已用时间:31.559(毫秒).执行号:3305.

SQL>commit;

操作已执行

已用时间:1.500(毫秒).执行号:3306.

SQL> selectcount( *) fromt2 ;

行号 COUNT(*)


1 11192

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

SQL>

查询11192花费2.608 毫秒。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服