MySQL如何实现百分位数计算

66次阅读
没有评论

共计 2175 个字符,预计需要花费 6 分钟才能阅读完成。

这篇文章主要介绍了 MySQL 如何实现百分位数计算,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让丸趣 TV 小编带着大家一起了解一下。

创建试验数据,5 天每天一百万随机数据, 总共 500w 数据

create table nums(id int not null primary key);
delimiter $$
begin
    truncate table nums;
    while s*2 =cnt do
        set s=s*2;
end $$

call pFastCreateNums(2000000);

drop table if exists t ;
create table t(
    query_time date,
    ts float,
    key(query_time,ts)
);

insert into t select 2018-07-01 ,round(100000*rand(),2) from nums where id =1000000;
insert into t select 2018-07-02 ,round(100000*rand(),2) from nums where id =1000000;
insert into t select 2018-07-03 ,round(100000*rand(),2) from nums where id =1000000;
insert into t select 2018-07-04 ,round(100000*rand(),2) from nums where id =1000000;
insert into t select 2018-07-05 ,round(100000*rand(),2) from nums where id =1000000;

首先,修正上文的 SQL,增加精度, 因为在大数据量下, 会有显著的误差。

select query_time,v,ts

from (

 select t6.query_time,t6.ts,v,seq,

 case when @gid=concat(seq, # ,query_time) then @rn:=@rn+1 when @gid:=concat(seq, # ,query_time) then @rn:=1 end s

 from (

 select query_time,ts,rn,percent,v,v-percent d,seq from (

 select t2.query_time,ts,rn,round(rn/total,10) percent from (

 select query_time,ts,

 case when @gid=query_time then @rn:=@rn+1 when @gid:=query_time then @rn:=1 end rn

 from (

 select * from t ,(select @gid:= ,@rn:=0) vars order by query_time,ts

 ) t1

 ) t2 inner join (

 select query_time,count(*) total from t group by query_time

 ) t3 on(t2.query_time=t3.query_time)

 ) t4 ,

 (select 0.71 v,1 seq union all select 0.81,2 union all select 0.91,3) t5

 ) t6 where d =0 order by query_time,v,d

) t7 where s=1 order by query_time,seq ;

在 ssd 环境下, 上文的 SQL 运行时长和结果如下.

148.813 s 

前文这个 SQL 的计算结果是非常精确的
但是计算时间和 采样点数量 有巨大关系. 假如原始数据是 100w,三个百分位数的采样, 则数据扩张到 300w;4 个百分位数的采样, 则数据扩张到 400w. 这是因为使用笛卡尔积扩张了数据的缘故.

优化版本:

select query_time,d,max(ts) ts from (

 select t2.query_time,ts,rn,round(rn/total,10) percent,

 case

 when 0.71 =round(rn/total,10) then 0.71

 when 0.81 =round(rn/total,10) then 0.81

 when 0.91 =round(rn/total,10) then 0.91

 end d

 from (

 select query_time,ts,

 case when @gid=query_time then @rn:=@rn+1 when @gid:=query_time then @rn:=1 end rn

 from (

 select * from t ,(select @gid:= ,@rn:=0) vars order by query_time,ts

 ) t1

 ) t2 inner join (

 select query_time,count(*) total from t group by query_time

 ) t3 on(t2.query_time=t3.query_time)

) t6

where d is not null

group by query_time,d

结果:

用时:
33.922 秒

感谢你能够认真阅读完这篇文章,希望丸趣 TV 小编分享的“MySQL 如何实现百分位数计算”这篇文章对大家有帮助,同时也希望大家多多支持丸趣 TV,关注丸趣 TV 行业资讯频道,更多相关知识等着你来学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-27发表,共计2175字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)