Spark dataset常用操作优化思路

select字段格式转换优化

hive数据和tidb数据类型不匹配问题,需要转换,有三种方案

1.dataset.withcolumn方法重写一个列

缺点:重新生成一个列,涉及到整个dataset分布的重写,加剧消耗磁盘io,也有性能问题,这种方式适合复杂的列进行计算后生成一个新值,然后这个新值进行join其他dataset操作

2.dataset.select(Column.udf())

只会在真正写的时候才进行转换操作,所以这种最适合格式进行转换,select 后一定要as别名一下,要不然会出现udf(name) 这个key找不到问题,正确为udf(name) as name

3.dataset.map(() -> )

缺点:map可能有单点问题,即所有的excutor会集中到一台进行map转换,数据量大会出现瓶颈问题

大dataset拆分优化

spark本身的机制其实可以处理数据量巨大的dataset,一般仅仅select并不会触发结算,只有count或者take才会操作,但是当一个dataset往mysql写时,就需要控制速度了,因为量大会导致mysql挂掉。

拆分有好多方法,

  1. 使用limit,但是不会返回一个新的dataset,返回的还是旧的,导致每个小的dataset操作的还是大的dataset,用mysql的分页逻辑不行:order by id limit 10这样不可行

  2. 使用 filter会返回一个新的dataset,和之前的dataset是脱离的,利用over (partition by order by )rownumber, 给整个dataset数据集中每一行都打一个标识,然后通过过滤 0 < rownumber < 100来进行分页

  3. 抽样查询

抽样查询可以减少spark扫描行数,加快执行速度,减少磁盘io,具体影响根据抽样率而定

String sql = "SELECT * FROM " + tableName + " TABLESAMPLE(BERNOULLI " + sampleFraction + ") LIMIT " + limit;

开窗函数

OVER 关键字表示把聚合函数当成聚合开窗函数而不是聚合函数。

OVER 关键字后的括号中还可以添加选项用以改变进行聚合运算的窗口范围。

如果 OVER 关键字后的括号中的选项为空,则开窗函数会对结果集中的所有行进行聚合运算。

开窗函数的 OVER 关键字后括号中的可以使用 PARTITION BY 子句来定义行的分区来供进行聚合计算。

注意:与 GROUP BY 子句不同,PARTITION BY 子句创建的分区是独立于结果集的,创建的分区只是供进行聚合计算的,而且不同的开窗函数所创建的分区也不互相影响。

1.ROW_NUMBER顺序排序

row_number() over(order by score) as rownum 表示按score 升序的方式来排序,并得出排序结果的序号

PartitionBy分组

2.RANK跳跃排序

rank() over(order by score) as rank表示按 score升序的方式来排序,并得出排序结果的排名号。

这个函数求出来的排名结果可以并列,并列排名之后的排名将是并列的排名加上并列数

简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第三名,也就是没有了第二名,但是有两个第一名

3.DENSE_RANK连续排序

dense_rank() over(order by score) as dense_rank 表示按score 升序的方式来排序,并得出排序结果的排名号。

这个函数并列排名之后的排名只是并列排名加1

简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第二名,也就是两个第一名,一个第二名

4.NTILE分组排名

ntile(6) over(order by score)as ntile表示按 score 升序的方式来排序,然后 6 等分成 6 个组,并显示所在组的序号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值