Spark SQL 生成遇到的问题及思考

2018-12-16  本文已影响0人  天之見證
问题 拙见 解释
什么时候使用DataFrameAPI 尽量少用 虽然写的时候很爽,当你回过头去看的时候,一团乱,不如一句sql直观
什么时候使用UDF 优先考虑使用内置的UDF,是在不行了再自己写 内置的UDF大家都知道功能,你自己写的,别人还要看你的逻辑,容易误解
什么时候使用纯sql 尽可能多的使用 sql是一种开发人员和分析人员都懂的语言,出于二者沟通成本低考虑,应优先考虑使用纯sql

1. SQL生成遇到的坑

最近工作中有一部分需要根据条件生成一些sql语句来完成, 因为输入的参数可能会有成百上千个 (因为是一个最基础的功能,所以尽量把参数做到最细的粒度), 当只有几个参数的时候,生成的sql 可以欢快的跑起来, 但是测了一个3000多个参数的时候,在SparkSQL里连执行计划都做不出来, codegen的时候直接64k 限制报错了, 查看了生成的sql 真是又臭又长, 里面有一大段重复的if-else 语句在里面, 这个语句会因为参数的增加而无限制增加, sql 类似如下:

select concat_ws(
    '\u0001', 
    if(col='1', 'a', null),
    if(col='2', 'b', null),
    ...
) as value
from table
where col in ('1', '2', ...)  -- 出于效率考虑加的这个where语句使sql更大了

2. 解决方法

1. 将if-else 的逻辑封装到一个udf

这样在codegen的时候可以避免这个问题, 同事提出的这个方法想了下,应该是可以的, 但是即便写一个udf 这相当于把if-else 挪到了一个函数里面去, 这个函数就得处理参数太多的问题, 想了一些办法,但因为一旦参数又增加, 比如到几百万这样的,一样会有问题

2. 做一个mapping表出来

select mapping.value
from table
inner join mapping
on table.col = mapping.col

因为参数太多

  1. 我就想什么结构可以容纳很多的参数,想到了 (这也可以看做一种数据结构)
  2. 然后再假定数据源存在一个表里了, 该怎么使用这个表

3. if-else 三阶段

  1. 单纯的if-else 语句: if(col='1', 'a', null)
  2. 使用一个mapmap_col[col_value]
  3. 使用一个mapping表: 类似本文这样一个例子

3. 一些建议

  1. 考虑更严重的情况 (参数更多)
  2. 更加抽象, 改变数据的形态 (单纯的一堆参数抽象出一张表)
  3. 试着限定一个更小的框, 只在sql 里做, 只使用表结构
上一篇下一篇

猜你喜欢

热点阅读