用于Sqoop拆分列的Oracle ROWID

时间:2016-09-05 09:34:58

标签: sqoop

我有一个巨大的oracle表(Transaction),我的oracle表中的数据在列"客户ID"由于少数地图制作者需要花费数小时才能完成工作,而其他地图制作者在几分钟内完成工作。我无法看到任何其他选项来避免偏移数据,因为这是唯一可以拆分的列。我们可以将客户ID,批次ID,SEQ NUM等其他列与多列拆分相结合,但我知道sqoop不支持拆分中的多列。

我的目标是提取特定时期的交易数据(即一个月的数据唯一的批日期)。

我在sqoop中使用10个映射器尝试了以下选项。

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

现在我正在考虑使用可能在映射器之间均匀分割行的ROWID。我想到使用边界查询来获得MIN& MAX ROW 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

如果这是正确的选择,或者有其他任何方式,请提供建议。

此外,我想知道我们是否可以使用多个拆分列名称。

2 个答案:

答案 0 :(得分:2)

提供--boundary-query只会节省评估分钟和混合值的时间。所有映射器都具有相同的范围查询。

在您的情况下,sqoop将生成边界查询,如 -

SELECT MIN(ROWID), MAX(ROWID) FROM (Select * From Transaction WHERE BATCH_DT=TO_DATE('03/31/2016','MM/DD/YYYY') ) t1

您可以在JDBC客户端上尝试此查询和自定义边界查询,以检查哪一个更快并使用该查询。

  

现在来到不均匀的映射器加载。

是的,你是对的。目前,sqoop不支持拆分中的多列。你必须选择一列。如果ROWID均匀分布(我假设是),您应该使用它。

所以,你的查询看起来不错。只需检查比较--boundary-query

修改

ROWID类型的Oracle没有正确的java类型问题。

在导入命令中添加--map-column-java ROWID=String以将其映射到Java的字符串。

答案 1 :(得分:1)

您是否有SEQ NUM的索引,如果是,那么您可以在--split-by中使用SEQ-NUM(我假设SEQ-NUM没有随机生成,它会以递增方式填充每个事务)。所以你的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