将select count作为结果插入表_判断数据库性能只能通过count(*)?No,这些优化方案了解一下!...

大多数用户在体验数据库时,接触到的最早的sql语句就是count(*),因此用户判断数据库性能时通常也会通过count(*)进行比较。但在执行时通常会出现一个问题:对某个表做count(*)时需对全表数据进行扫描,当表中包含数据量较大的字段时,IO将会成为数据扫描的瓶颈。

419afdc6f091758a84b87062dd79d592.png

数据扫描瓶颈有哪些优化方式?

e7266754658f6102ceb4dddb8bba5120.gif

针对上述问题,为解决全表扫描带来的IO开销的方案大致可分为三类:

第一类是减少扫描数据;

第二类是通过并行方式扫描数据;

第三类是通过预估值计算方式获取结果。

根据上述三种方案,我们给出以下四种优化方式:

01

减少扫描数据

(1)使用列存

顾名思义,列存是按列存储的。当使用count(*)查询时,只需要扫描一列数据做count统计,而并非全表,这样,IO开销几乎是行存的1/列数,即效率是行存的列数倍。在实际使用中,因为每列字段长度的原因,使用列存时count(*)效率往往要比这个值还要高得多。

(2)使用Index only scan

使用主键的Index only scan,count(*)仅需扫描主键的索引链表即可,不必扫描所有的数据块,因此可大大减少IO开销。

02

并行扫描数据

(1)MPP架构

使用MPP架构的好处是让数据分布到各个计算节点上。这样,在使用count(*)查询时,每个计算节点都会去统计该节点的数据量,最终汇聚返回总的数据量,这种方式可以更好地利用CPU和磁盘达到并行扫描的效果,节省扫描时间。

03

预估值计算

(1)Hyperloglog

HyperLogLog算法来源于论文《HyperLogLog the analysis of a near-optimal cardinality estimation algorithm》,可以使用固定大小的字节计算任意大小的distinct value。由于HLL是概率计算算法,它依赖于数据的均匀分布,在使用时往往需要我们首先利用HLL对每个元素进行哈希,以使数据分布更加均匀。

因此,任何可以哈希的数据类型都可以使用HLL算法做统计估算,HLL算法在数据库的估值统计计算方面起到了重要作用。

哪些产品能提供具体优化方案?

e7266754658f6102ceb4dddb8bba5120.gif

综合上述4种优化方式,人大金仓悉心打造的MPP数据库KADB具备以上所有特性方案,具体包括:

(1)列存

KADB支持可压缩列存储,压缩比可达1:10。建表语句如下:

create table t_count(id uuid, num int) with

(appendonly=true,orientation=column,compresstype=zlib,compresslevel=5);

(2)Index only scan

KADB支持index only scan,执行计划如下:

explain select count(*) from t_count ;

QUERY PLAN

------------------------------------------------------------------------------------------------------------------

Aggregate (cost=17403254.38..17403254.39 rows=1 width=8)

-> Gather Motion 8:1 (slice1; segments: 8) (cost=17403254.27..17403254.37 rows=1 width=8)

-> Aggregate (cost=17403254.27..17403254.28 rows=1 width=8)

-> Index Only Scan using idx_t_count_id on t_count (cost=0.19..17153253.65 rows=12500031 width=0)

(3)MPP架构

KADB是人大金仓基于Kingbase ES 单机数据库打造的MPP数据库,具有一切皆并行的特点

(4)Hyperloglog

KADB集成了HLL插件。具体操作如下:

创建计数表,并插入1亿条数据,id列重复值较少:

create table t_count(id uuid, num int);

--创建插入函数,id值为uuid,无重复值

create or replace function f_insert(i int) returns setof record as $$

select uuid_generate_v4(), generate_series(1,i);

$$ language sql;

--插入数据

insert into t_count select * from f_insert(100000000) as t(id uuid, num int);

创建HLL统计表,记录唯一值:

create table daily_id_hll

as select

gp_hyperloglog_accum(id)

from

t_count;

最终通过HLL算法预估出t_count的条数

select gp_hyperloglog_get_estimate(gp_hyperloglog_accum) from daily_id_hll;

gp_hyperloglog_get_estimate

-----------------------------

99651193.2825577

(1 row)

误差率在0.35%左右

select (100000000-99651193.2825577)/100000000;

?column?

------------------------

0.00348806717442300000

(1 row)

MPP数据库KADB优化效果如何?

e7266754658f6102ceb4dddb8bba5120.gif

在此,我们导入1亿条数据进行测试,数据总量大小为203GB,测试count(*)比对效率如下:

7ee9d86344529e9f960ed1ca3acea49f.png

7a7f58237eb3fa25cc138fbf2faedfaf.png

综上总述,KADB具备以上所有优化方式的解决方案能力,可根据不同需求优化count(*)查询。在用户实际应用场景中,

面对实时性要求较高但准确度要求不太高的数据可视化服务,我们通常提供Hyperloglog优化方案;

面对实时性要求不太高但准确度要求高的统计服务,我们通常提供列存优化方案。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值