当我们在开发 ETL 的过程中, 面向应用的数据表经常会遇到行转列问题. 会将指标名称作为一列内容. 这样开发会有大量重复 ETL 和大量的 UNION ALL SQL. 如果每个 UNNION ALL SQL 都要执行一遍势必要消耗大量计算资源.
那如何高效解决这种问题呢?
1, 传统数据库 (支持 with)
使用 with 语句将 SQL 逻辑封装成一张临时表, 下面的 SQL 在这张临时表的基础上进行计算. 这样只需要进行一次计算多次使用. 并且临时表是在会话内生效, 会话关闭后临时表自动消失. 不会影响到其他会话.
2,HIVE
在 hive 里也可以使用 with 语句模拟传统数据库操作, 但需要注意的是, hive 只是将 with 的脚本封装, 执行的时候并不会创建临时表. 可以想象他是一张视图表, 只记录了 SQL 逻辑, 不存储数据.
在 XT 中如何解决这个问题呢, 因为 hive 不支持会话, 我们可以使用创建临时的数据表的方式来解决. 但是防止数据表中的数据混乱, 我们要在一个 ETL 中模拟会话, 使用先尝试删除, 再创建, 再删除的操作流程.
- drop table if exists XXX.XXX;
- create table XXX.XXX as
- select
ETL 逻辑
drop table if exists XXX.XXX;
这样就可以既可以很高效的进行 ETL 开发, 又可以节省计算资源.
但这样也会带来一个问题, 当我们大量刷数据的时候无法并行刷新, 会有多个 ETL 使用同一张临时数据表, 并且每个任务都会执行一遍删除操作, 很容易造成数据错乱, 锁表.
这种问题又该如何解决?
方法其实很简单, 我们将 ETL 的临时数据表表名后面增加一个变量就可以达到并行的时候每个任务都会有自己的临时数据表了.
所以完整的创建临时数据表的开发脚本应该是这样的:
- drop table if exists XXX.XXX_$now.datekey;
- create table XXX.XXX_$now.datekey as
- select
ETL 逻辑
drop table if exists XXX.XXX_$now.datekey;
这种方式适用于那些场景?
数据源数据量大, 重复查询数据源获取数据
将多个指标列转至, 大量重复编写查询脚本
来源: http://www.bubuko.com/infodetail-2616774.html