ODPS 2.0 支持了很多新的集合命令(專有云升級到3版本後陸續支持),簡化了日常工作中求集合操作的繁瑣程度。增加的SQL語法包括:UNOIN ALL、UNION DISTINCT並集,INTERSECT ALL、INTERSECT
DISTINCT交集,EXCEPT ALL、EXCEPT DISTINCT補集。
語法格式如下:
select_statement UNION ALL select_statement;
select_statement UNION [DISTINCT] select_statement;
select_statement INTERSECT ALL select_statement;
select_statement INTERSECT [DISTINCT] select_statement;
select_statement EXCEPT ALL select_statement;
select_statement EXCEPT [DISTINCT] select_statement;
select_statement MINUS ALL select_statement;
select_statement MINUS [DISTINCT] select_statement;
用途:分別求兩個數據集的並集、交集以及求第二個數據集在第一個數據集中的補集。
參數說明:
• UNION: 求兩個數據集的並集,即將兩個數據集合併成一個數據集。
• INTERSECT:求兩個數據集的交集。即輸出兩個數據集均包含的記錄。
• EXCEPT: 求第二個數據集在第一個數據集中的補集。即輸出第一個數據集包含而第二個數據集不
包含的記錄。
• MINUS: 等同於EXCEPT。
實際項目中有一個利用兩日全量數據,比對出增量的需求(推送全量數據速度很慢,ADB/DRDS等產品數據量超過1億,建議試用增量同步)。我按照舊的JOIN方法和新的集合方法做了下比對驗證,試用了下新的集合命令EXCEPT ALL。
測試
-- 方法一:JOIN
-- other_columns 代表很多列
create table tmp_opcode1 as
select * from(
select uuid,other_columns,opcode2
from(
-- 今日新增+今日變化
select
t1.uuid
,t1.other_columns
,case when t2.uuid is null then 'I' else 'U' end AS opcode2
from prject1.table1 t1
left outer join prject1.table1 t2
on t1.uuid=t2.uuid
and t2.dt='20200730'
where t1.dt='20200731'
and(t2.uuid is null
or coalesce(t1.other_columns,'')<>coalesce(t2.other_columns,''))
union all
-- 今日刪除
select
t2.uuid
,t2.other_columns
,'D' as opcode2
from prject1.table1 t2
left outer join prject1.table1 t1
on t1.uuid=t2.uuid
and t1.dt='20200731'
where t2.dt='20200730'
and t1.uuid is null)t3)t4
;
Summary:
resource cost: cpu 13.37 Core * Min, memory 30.48 GB * Min
inputs:
prject1.table1/dt=20200730: 32530802 (946172216 bytes)
prject1.table1/dt=20200731: 32533538 (947161664 bytes)
outputs:
prject1.tmp_opcode1: 4506 (271632 bytes)
Job run time: 26.000
-- 方法二:集合
-- other_columns 代表很多列
create table tmp_opcode2 as
select * from(
select t3.*
from(
-- 今日新增+今日變化
select uuid,other_columns,'I' as opcode2
from(
select uuid,other_columns
from prject1.table1
where dt = '20200731'
except all
select uuid,other_columns
from prject1.table1
where dt = '20200730')t
union all
-- 今日刪除
select
t2.uuid
,t2.other_columns
,'D' as opcode2
from prject1.table1 t2
left outer join prject1.table1 t1
on t1.uuid=t2.uuid
and t1.dt='20200731'
where t2.dt='20200730'
and t1.uuid is null)t3)t4
;
Summary:
resource cost: cpu 35.92 Core * Min, memory 74.26 GB * Min
inputs:
prject1.table1/rfq=20200730: 32530802 (946172216 bytes)
prject1.table1/rfq=20200731: 32533538 (947161664 bytes)
outputs:
prject1.tmp_opcode2: 4506 (259416 bytes)
Job run time: 66.000
性能
集合的方法比JOIN的方法,在資源(1倍)使用和時間(1倍)上都有較多的劣勢。建議實際使用JOIN方法。
結果
通過多種方法比對驗證,兩種方法的增量識別均正確,可以向下遊提供增量數據。