在SQOOP中使用Where子句的问题

时间:2016-10-22 07:42:56

标签: sqoop

我正在尝试使用--where选项通过使用以下命令将orders表与order_items表连接来获取条件数据:

sqoop import \
--connect "jdbc:mysql://quickstart.cloudera:3306/retail_db" \
--username retail_dba \
--password cloudera \
--query "Select * from orders o join order_items oi on o.order_id = oi.order_item_order_id where  \$CONDITIONS " \
--where "order_id between 10840 and 10850" \
--target-dir /user/cloudera/order_join_conditional \
--split-by order_id

现在我不知道这有什么不对,因为当我在MySQL中运行相同的查询时,我得到41条记录是正确的但是当我在sqoop中运行此命令时,它将转储所有172198条记录。我不明白发生了什么事,发生了什么事。

1 个答案:

答案 0 :(得分:0)

当您运行并行导入时,Sqoop将使用--split-by中指定的参数值替换$CONDITIONS参数并生成不同的查询(将由不同的映射器执行)。例如,Sqoop将首先尝试查找order_id的最小值和最大值,并根据映射器的数量,尝试针对order_id的整个可能值范围的不同子集执行查询。

这样,您的查询将在内部转换为不同的并行查询,如下所示:

SELECT * FROM orders o join order_items oi on o.order_id = oi.order_item_order_id
 WHERE (order_id >=0 AND order_id < 10000)

SELECT * FROM orders o join order_items oi on o.order_id = oi.order_item_order_id
 WHERE (order_id >=1000 AND order_id < 20000)

...

因此,在这种情况下,您单独指定的--where子句将不会被使用,并且您最终将获得所有记录。但在您的特定情况下,您并不需要--split-by标志,因为您只对特定(且非常有限)的值范围感兴趣。所以你可以改用它:

sqoop import \
--connect "jdbc:mysql://quickstart.cloudera:3306/retail_db" \
--username retail_dba \
--password cloudera \
--query "Select * from orders o join order_items oi on o.order_id = oi.order_item_order_id WHERE (order_id BETWEEN 10840 AND 10850)" \
--target-dir /user/cloudera/order_join_conditional \
-m 1

另请注意最后的-m 1(由devツ指出)代表--num-mappers,并允许您告诉Sqoop您只想使用一个映射器进行导入过程(因此,没有并行性。)

如果值范围较大,您可以使用--split-by并在自由格式查询中使用where条件,并使用并行性:

sqoop import \
--connect "jdbc:mysql://quickstart.cloudera:3306/retail_db" \
--username retail_dba \
--password cloudera \
--query "Select * from orders o join order_items oi on o.order_id = oi.order_item_order_id WHERE (order_id BETWEEN 10840 AND 10850) AND \$CONDITIONS" \
--target-dir /user/cloudera/order_join_conditional \
--split-by order_id