表行计数器说明
默认情况下,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 毫秒。
文章
阅读量
获赞