Doris2.0的Analyze功能,能让查询变快不?

来源:安瑞哥是码农

就在我写完上一篇,Doris升级到2.0.2之后跟之前Doris1.2.3的查询效率对比文章后。


估计是对我这个新旧版本的对比结果不太满意,有社区的小伙伴私信告诉问我,测试2.0.2的时候,是否有用 ANALYZE 功能,并告诉我,它是2.0新优化器很重要的一个模块,目的就是加速查询用的。


然后扔给我一个相关的链接,我顺着这个链接点开一看,确实是一片陌生的内容,它位于官方文档的「查询加速」模块下,相比于我之前看到的1.2版本的文档,新的2.0又多了几个新花招。


1.2版本的加速功能



2.0新版本的加速功能


对比一下,从文档结构描述来看,2.0一下子多了4个新的查询加速功能,咱后续考虑一个个来测测看。


但今天,我们先把目光聚焦在这个统计信息,也就是对表的 ANALYZE 功能,看到底是怎么玩的?



0. 先看文档


既然是一项新功能,自然第一步就是看官方文档是怎么描述这玩意的。


这个推荐我去看的,表优化查询(查询加速)功能叫「统计信息」,打开文档一看呢,内容还挺多的,里面包含的信息量有些大。


老实说,这个文档内容虽然详尽,篇幅很长,但并没有到做到结构清晰、言简意赅(我个人认为),估计会让很多第一次阅读的同学没有耐心全部读完,我通读了两遍,现把我对这部分「统计信息」内容的理解,总结如下:


1,从文档结构中的命名来看,「统计信息」顾名思义就是对表中的数据进行各种基础信息、和共性属性的统计,因为Doris是列式数据库,所以这个统计,会对比如每一列数据的总条数、基数、最大值、最小值、空值情况等进行各种汇总;


2,这个统计,跟所有对数据库的查询进行优化的思想一样,本质就是预计算,将一些不需要跟业务规则强绑定的共性计算,提前给做了,为后续的业务查询尽可能提供加速便利;


3,这个所谓的统计信息,可以在后续基于业务的复杂查询时,为数据库的查询优化器,提供优化依据,生成最优查询计划。


那到底,这个所谓的「统计信息」是怎么玩的?以及它到底能不能真正实现我们的业务查询加速,我们还是老规矩,测试一下便知。



1. 先看怎么玩的


从文档的描述,以及结合我的实践来看,这个针对表的统计(ANALYZE),在新的版本里,必须要通过手动触发才可以,虽然文档的最后说这个full auto analyze功能是默认开启的。



但我通过在新的2.0集群中新建了一张表之后,并没有发现这个analyze有启动的迹象(我等了几个小时都没有启动,那这肯定不是自动的)。


对新建的表灌入数据后,并没有对其analyze


是我的姿势不对吗?还是确实不能这么玩?

此外呢,从文档描述中来看,说它还可以通过额外对表设置AUTO的方式,让其自动对表的数据进行统计(ANALYZE),设置方式如下:



可以看到,对应确实产生了一个后台的job id(截图部分没有显示出来),很快这个analyze就完成了。



看一眼这个analyze的统计结果:


表粒度的analyze结果


列粒度的analyze结果


但是,当我继续往这表里再写入一些数据时,按理说,既然这个 analyze 被设置为 auto 模式了,那我后续写数据进去,这个对于的统计结果应该要更新才对。


可是,它不,当我再次往里写入2w条记录数据时,这个统计结果依旧岿然不动。


往里再写2w条记录


多次执行,统计结果没有变化


尝试了几次,没招了。(PS:后续我又尝试用 period 和 incremental的配置方式,还是不行)


只能再次手动执行analyze命令,这才正常。



注意,这里之所以总数量少于3w(1w + 2w),原因在于后面写进去的2w数据跟之前的存在少量重复,而该表是个去重表模型导致。


但是,即便是这样,这个统计的结果依然存在槽点。


槽点1:


说好的,针对表粒度的统计结果,应该有6个字段的统计信息,但我这查询出来的,却只有3个。


官方文档给出的统计信息是这样的:


统计结果有6个字段


而我运行的统计信息,是这样的:


统计结果只有3个字段


谁能告诉我为什么?莫非我升级了个假的 2.0。


槽点2:


既然是统计(analyze),那咱是不是要统计准确一点?


那为毛用这种方式统计出来的一些结果,跟我直接用查询语句查出来的还不一样呢?


比如对于上面这张表来说,authority_record 这个字段的ndv值,也就是 count distinct 值为6291,但是我用SQL语句查出来,居然是6321。


不止这个字段,其他字段的这个ndv统计也都基本一个鸟样,就很迷。


疑点:


那既然这个analyze功能,只能通过每次需要时,去手动去触发(目前我看到是的),那它存在的意义有用多大呢?


莫非需要我额外再去写个脚本,去定期执行?而且它这个统计的信息很多都不准,我不知道到底能给这个查询优化器加多少速。


另外,以上还只是这个analyze功能,基于列的普通统计。


新版本的Doris说还支持对列的「直方图统计」,但是在我的这个集群里,却这么着都实现不了


官方文档给的示例:


我集群的执行情况:


这又是啥情况呢?明明升级成功了呀。



2. 能真的对查询加速吗


既然说这个对表的 analyze,可以加速我们的业务查询,那咱来就来实际测试看看,到底是不是真的?


由于在实际的查询过程中,对于同一个查询SQL,即便排除任何外界因素影响下,其查询耗时也会有所波动,所以对于查询效率对比,只要差别不大,我们就暂且认为没有变化。


(PS:为了不让文章显得过于冗长,以下查询效率的截图就先不放了,直接给结论)


2.1  找出target_ip为空时(实际数据为双引号),此时每个不同domain的个数(要求domain统一小写)


查询SQL为:


select 
domain
count(domainas count 
from 
(
select 
lower(domainas domain 
from 
logs_from_spark01 
where target_ip='""'
)t  
group by 
t.domain;


开启analyze前后,几乎没有变化



2.2 查询上网次数最多的前100个client_ip,以及他们分别的归属地是哪里

查询SQL如下:


select 
t1.client_ip,
t2.nature,
t2.province,
t2.city,
t1.count
from
(
select 
client_ip,
count(client_ip) as count 
from 
logs_from_spark01 
group by 
client_ip 
order by 
count desc 
limit 100
)t1
inner join 
logs_from_spark01 t2
on 
t1.client_ip=t2.client_ip
group by 
client_ip,
nature,
province,
city,
count


开启analyze前后,几乎没有变化


2.3 count distinct的效率对比


通过对高基列的效率对比。

证实analyze优化后,效率几乎没有变化(快了约0.3秒)

2.4 以分钟为标准,找出连续上网次数最多的前100个client_ip

查询SQL:


select
client_ip,
max(row_num2) as max
from
(
select 
client_ip,
row_num2,
date_min
from
(
select
client_ip,
sub_date,
row_number() over (partition by client_ip,sub_date) as row_num2,
date_min
from
(
select 
client_ip,
date_min,
row_number() over (partition by client_ip order by date_min) as row_num,
minutes_sub(to_date(date_min), row_num) as sub_date
from
(
select client_ip,
date_min,
row_number() over (partition by client_ip,date_min order by date_min) as row_num
from
(
select 
client_ip, 
minute_floor(timeAS date_min
from 
logs_from_spark01 
where  
length(time)=14 
and 
time like '20220730%' 
)t
) A
where A.row_num=1
) B
) C
)D
group by 
D.client_ip
order by max desc
limit 100


开启analyze前后,查询效率没有变化



2.5 查询出 client_ip 中包含的所有国家、省份、城市,以及运营商


查询SQL:


select 
nature,
province,
city,
operator 
from 
logs_from_spark01 
group by 
nature,
province,
city,
operator;


开启analyze前后,查询效率几乎没有变化


2.6 查询表中不重复数据的数据总条数


查询SQL:


SELECT 
count(*) 
FROM 

SELECT  
*, 
row_number() over (partition by client_ip, nature, province, city, operatordomaintime, target_ip, rcode, query_type, authority_record, add_msg, dns_ip) as row_num 
FROM 
logs_from_spark01 
)t 
WHERE t.row_num =1;

开启analyze前后,查询效率几乎没有变化(甚至慢了一丢丢)



最后

从我的这次基于对Doris2.0新推出的 ANALYZE 功能实测来看,确实对实际的查询几乎没有什么帮助(仅基于我的场景而言)。

虽然说Doris在2.0的版本中,加入了一些试图加速查询的「黑科技」,但即便如此,就如我之前说的,这些玩意到底实不实用,还必须得在真刀真枪的真实环境中经受住考验才行。

否则,整一些花拳绣腿,着实没啥意义。当然,Doris还在持续成长,我们应该给予一定的宽容和理解,并怀抱一定的耐心,期待它越来越好。

请使用浏览器的分享功能分享到微信等