按列拆分的sqoop的oracle rowid

iq3niunx  于 2021-06-03  发布在  Sqoop
关注(0)|答案(2)|浏览(341)

我有一个巨大的oracle表(transaction),我的oracle表中的数据在“customer id”列上有倾斜的数据,这是因为少数Map者在几个小时内完成工作,而其他Map者在几分钟内完成工作。我看不到任何其他选项来避免数据倾斜,因为这是唯一可以拆分的列。我们可以将其他列(如customer id、batch id、seq num)与multi-column split结合起来,但我知道sqoop不支持split by中的multi-column。
我的目标是提取特定期间的事务数据(即,对于一个月的数据,批处理日期是唯一的)。
我用10个Map器在sqoop中尝试了以下选项。

--split-by "my column name"           //for example customer id
--where "my query condition"         //for example batch date

现在我正在考虑使用rowid,它可以在Map器之间均匀地分割行。我考虑使用边界查询来获取最小和最大行id。下面是我想要使用的sqoop命令。

sqoop import \
--table Transaction \
--split-by ROWID \
--where "BATCH_DT=TO_DATE('03/31/2016','MM/DD/YYYY')" \
--boundary-query "SELECT MIN(ROWID) AS MIN, MAX(ROWID) AS MAXL FROM Transaction WHERE BATCH_DT=TO_DATE('03/31/2016','MM/DD/YYYY') GROUP BY CUSTOMERID, BATCHNO,BATCHSEQNO " \
--num-mappers 10 \
--target-dir /user/trans

需要建议,如果这将是正确的选择或有任何其他方式。
另外,我想知道我们是否可以使用列名多分裂的任何机会。

nzrxty8p

nzrxty8p1#

您是否在seq num上有索引,如果有,那么您可以使用seq num in--split by(我假设seq num no随机生成,它以增量方式为每个事务填充)。所以您的sqoop命令可能如下所示

sqoop import \ 
--table Transaction \
--split-by SEQ-NUM \
--where "BATCH_DT=TO_DATE('03/31/2016','MM/DD/YYYY')" \ 
--num-mappers 10 \
--target-dir /user/trans
iyfjxgzm

iyfjxgzm2#

提供 --boundary-query 只会节省您评估最小值和最大值的时间。所有Map器都将具有相同的范围查询。
在您的例子中,sqoop将生成边界查询,如- SELECT MIN(ROWID), MAX(ROWID) FROM (Select * From Transaction WHERE BATCH_DT=TO_DATE('03/31/2016','MM/DD/YYYY') ) t1 您可以在jdbc客户机上尝试这个查询和自定义边界查询,以检查哪个查询更快,并使用那个查询。
现在来看看不均匀的Map。
是的,你说得对。目前,sqoop不支持splitby中的多列。你必须选择一列。如果 ROWID 是均匀分布的(我想是的),你应该用它。
所以,你看起来不错。只是检查比较 --boundary-query .

编辑

没有正确的java类型问题 ROWID 甲骨文的类型。
添加 --map-column-java ROWID=String 在import命令中,将其Map到java的字符串。

相关问题