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挂掉。
拆分有好多方法,
-
使用limit,但是不会返回一个新的dataset,返回的还是旧的,导致每个小的dataset操作的还是大的dataset,用mysql的分页逻辑不行:order by id limit 10这样不可行
-
使用 filter会返回一个新的dataset,和之前的dataset是脱离的,利用over (partition by order by )rownumber, 给整个dataset数据集中每一行都打一个标识,然后通过过滤 0 < rownumber < 100来进行分页
-
抽样查询
抽样查询可以减少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 个组,并显示所在组的序号。
510

被折叠的 条评论
为什么被折叠?



