面向线下跑批、在线查询等数据计算场景
采用SQL语法的、应用于OLAP场景的数据库
其它数据分析与统计技术
中央数据仓库承担全行的数据任务,负担过重,只能分配给BI系统5个并发
仅对少量高频数据,DB2也无法胜任实时查询,更无法实现数据路由,需要用户选择数据源
QDBase存储少量高频数据,大量低频数据仍存储在数据仓库中,避免重复建设
QDBase承担绝大多数的高频计算任务,剩下少量低频任务自动路由到中央数据仓库
Vertica不支持存储过程,要写异常复杂的嵌套SQL准备数据,经常还要借助Java代码
与MySQL的混合计算时要先将MySQL数据转入,繁琐、不实时、数据库臃肿
The best use for us is to pass parameters to the Vertica database.
Each cell becomes a data array that are easy to use, compare and manipulate. It is very logical and you have made it user friendly.SELECT MAX(ContinuousDays) FROM (SELECT COUNT(*) ContinuousDays FROM (SELECT SUM(UpDownTag) OVER ( ORDER BY TradeDate) NoRisingDays FROM (SELECT TradeDate, CASE WHEN Price>LAG(price) OVER ( ORDER BY TradeDate) THEN 0 ELSE 1 END UpDownTag FROM Stock ) ) GROUP BY NoRisingDays )
SQL对有序运算支持不足,未直接提供有序分组,只能采用迂回思路,写成四层嵌套的形式
这样的句子不仅很难写出来,写出来想看懂也不容易
面对复杂的业务逻辑,SQL的复杂度会陡增,既难懂又难写
这并非罕见需求,现实中数千行的SQL代码中这种情况比比皆是,严重影响开发和维护效率
SELECT TOP 10 * FROM Orders ORDER BY Amount DESC
这个查询用了ORDER BY,严格按此逻辑执行,意味要将全量数据做排序,性能将很差
我们知道有不必全排序而完成这个运算的办法,但用SQL无法描述,只能寄希望于数据库的优化引擎
简单情况(比如本句),很多数据库都能优化,但情况再复杂一些,数据库优化引擎就会晕了
下面的分组内取前N名,SQL无法直接描述了,还是要采用迂回思路利用窗口函数写成子查询
面对这种迂回写法,数据库优化引擎也不会优化了,只能去执行排序
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Area ORDER BY Amount DESC) rn FROM Orders ) WHERE rn<=10
A | |
1 | =Stock.sort(TradeDate).group@i(Price< Price[-1]).max(~.len()) |
这句SPL和前面SQL的运算逻辑相同,但SPL提供 有序分组运算,描述起来直观简洁
A | ||
1 | =file(“Orders.ctx”).open().cursor() | |
2 | =A1.groups(;top(10;-Amount)) | 金额在前10名的订单 |
3 | =A1.groups(Area;top(10;-Amount)) | 每个地区金额在前10名的订单 |
SPL将TopN视为返回集合的聚合运算,避免全排序;全集和分组时写法类似,不再迂回
with e1 as ( select uid,1 as step1,min(etime) as t1 from event where etime>= to_date('2021-01-10') and etime < to_date('2021-01-25') and eventtype='eventtype1' and … group by 1), e2 as ( select uid,1 as step2,min(e1.t1) as t1,min(e2.etime) as t2 from event as e2 inner join e1 on e2.uid = e1.uid where e2.etime>= to_date('2021-01-10') and e2.etime < to_date('2021-01-25') and e2.etime > t1 and e2.etime < t1 + 7 and eventtype='eventtype2' and … group by 1), e3 as ( select uid,1 as step3,min(e2.t1) as t1,min(e3.etime) as t3 from event as e3 inner join e2 on e3.uid = e2.uid where e3.etime>= to_date('2021-01-10') and e3.etime < to_date('2021-01-25') and e3.etime > t2 and e3.etime < t1 + 7 and eventtype='eventtype3' and … group by 1) select sum(step1) as step1, sum(step2) as step2, sum(step3) as step3 from e1 left join e2 on e1.uid = e2.uid left join e3 on e2.uid = e3.uid
SQL缺乏有序计算且集合化不够彻底,需要迂回成多个子查询反复JOIN的写法,编写理解困难而且运算性能非常低下
限于篇幅,只写了三步漏斗,再增加步骤时还要增加子查询
A | |
1 | =["etype1","etype2","etype3"] |
2 | =file("event.ctx").open() |
3 | =A2.cursor(id,etime,etype;etime>=date("2021-01-10") && etime < date("2021-01-25") && A1.contain(etype) && …) |
4 | =A3.group(uid).(~.sort(etime)) |
5 | =A4.new(~.select@1(etype==A1(1)):first,~:all).select(first) |
6 | =A5.(A1.(t=if(#==1,t1=first.etime,if(t,all.select@1(etype==A1.~ && etime>t && etime < t1+7).etime, null)))) |
7 | =A6.groups(;count(~(1)):STEP1,count(~(2)):STEP2,count(~(3)):STEP3) |
SPL提供有序计算且集合化更彻底,直接按自然思维写出代码,简单且高效。
这段代码能够处理任意步骤数的漏斗,只要改变参数即可
Java过于原生,缺少必要数据类型和计算库,导致应用程序员写出难或写不出
Calendar cal = Calendar.getInstance(); Map < Object, DoubleSummaryStatistics> c = Orders.collect(Collectors.groupingBy( r -> { cal.setTime(r.OrderDate); return cal.get(Calendar.YEAR) + "_" + r.SellerId; }, Collectors.summarizingDouble(r -> { return r.Amount; }) ) ); for(Object sellerid:c.keySet()){ DoubleSummaryStatistics r =c.get(sellerid); String year_sellerid[]=((String)sellerid).split("_"); System.out.println("group is (year):"+year_sellerid[0]+"\t (sellerid):"+year_sellerid[1]+"\t sum is:"+r.getSum()); }
高性能算法难以实现
没有通用的高性能存储
Python的DataFrame并不擅长处理复杂情况下的结构化数据计算
import pandas as pd import datetime import numpy as np import math def salary_diff(g):max_age = g['BIRTHDAY'].idxmin()min_age = g['BIRTHDAY'].idxmax()diff = g.loc[max_age]['SALARY']- g.loc[min_age]['SALARY']return diffemp['BIRTHDAY']=pd.to_datetime(emp['BIRTHDAY'])salary_diff= emp.groupby('DEPT').apply(salary_diff)print(salary_diff)
运算完善度方面仍有不足
语法一致性差
大数据能力差
无通用高性能存储
SPL特别适合复杂过程运算
专门针对结构化数据表设计
QDBase采用Java开发,可独立运行,也可无缝集成到应用
直接使用多个数据源混合计算
自有数据存储格式,集文件、组表
可用树状目录方式按业务分类存储数据
路由能力实现低成本高性能全量数据分析
用开放的多源混算能力支撑低风险高性能强实时HTAP
QDBase基于全新的计算模型,无开源技术可以引用,从理论到代码全部自主创新
基于创新理论的QDBase不能再使用SQL实现高性能,SQL无法描述大部分低复杂度算法
QDBase 完全用纯Java开发,可以在任何有JVM的操作系统下运算,包括虚拟机、云服务器以及容器,甚至可以运行在Android 上。
QDBase 提供了标准的JDBC驱动,可被Java应用无缝集成调用。
对于非Java应用,QDBase提供了HTTP/RESTFul调用接口。
作为拥有良好集成性的Java产品,可以无缝与各种 Java 框架和应用服务器集成使用,其逻辑地位与自写的Java代码等同
对于计算型框架(比如 Spark),虽然QDBase能被无缝集成,但并没有实际意义,QDBase可以替代Spark计算
特别地,QDBase自有流式计算能力,不需要被流计算框架(比如 Flink)集成,通常会更好的功能和性能
当然没问题!
不过,因为数据库I/O性能不佳, QDBase在这种情况下不能保证高性能, 而且数据库通常也不提供低复杂度算法需要的存储。要获得高性能,则需要QDBase自己存储数据
QDBase使用自有格式的文件来存储数据,任何操作系统下的文件系统都支持,包括网络文件系统。这样,QDBase可以天然地实现存算分离机制。
嵌入应用使用时,可靠性由应用保障
独立使用时,提供负载均衡和容错机制,但单任务可能失败,仅适合小规模集群
不提供故障后自动恢复功能
云版本的弹性计算机制在分配 VM 时会避开当前失效的节点,一定程度实现高可用
可使用提供的接口,调用 Java 写的静态函数来扩展功能
QDBase也开放了自定义函数的接口,注册后即可在SPL中使用
和RDB相比
QDBase的元数据能力相对不成熟,大部分计算要从访问数据源(文件)开始,对于简单运算会有些麻烦。
和Hadoop/MPP相比
QDBase提供有集群能力,但缺乏机会历练。
历史上,QDBase多次用单机替代原有的集群,仍获得同样甚至更高的性能。
和Python相比
SPL 正在发展人工智能功能,但目前和Python相差还比较远。
SPL不是 SQL 体系的计算引擎,目前仅支持小数据量下的简单SQL且不保障性能。可以认为QDBase不支持SQL,当然也不会和任何SQL存储过程兼容。
未来会发展出支持 SQL 的双引擎,但仍然很难保证高性能和大数据,仅仅是让存量的 SQL 代码易于迁移
目前还没有。
SQL语句的信息不足, 需要猜出其目标才能设计合理的优化路径。我们优化SQL的经验远不如传统数据库厂商,这时候直接把SQL转换成SPL通常会导致更差的性能。
SPL专门用于低代码和高性能
SPL语法很容易,有Java/SQL基础者只要数小时即可入门,数周就能熟练
“难”,高性能算法有点难, 需要学习更多算法知识
“不难”,一旦学会,很多高性能任务都成为“套路”
最初的1-2个场景,由我方工程师介入配合用户实现
大多数程序员习惯了SQL思维方式,不熟悉SPL的思维方式,需要用一两个场景训练和理解
性能优化套路经历过也就学会了,算法设计和实现并不是那么难
授人以鱼不如授人以渔!
大数据处理速度比传统方案平均提高1个数量级
语法过程化,符合自然思维
丰富类库
多源混合计算
独立、嵌入多种应用方式
单机顶集群,减少硬件开销
绿色环保
开发、硬件、运维成本降低X倍