我使用AWS-EMR来运行我的Hive查询,并且在运行hive版本0.13.1时出现性能问题。
较新版本的hive需要大约5分钟才能运行10行数据。但230804行的相同脚本需要2天才能运行。我该怎么做才能分析并解决问题?
示例数据:
表1:
hive> describe foo;
OK
orderno string
Time taken: 0.101 seconds, Fetched: 1 row(s)
table1的示例数据:
hive>select * from foo;
OK
1826203307
1826207803
1826179498
1826179657
表2:
hive> describe de_geo_ip_logs;
OK
id bigint
startorderno bigint
endorderno bigint
itemcode int
Time taken: 0.047 seconds, Fetched: 4 row(s)
表2的样本数据:
hive> select * from bar;
127698025 417880320 417880575 306
127698025 3038626048 3038626303 584
127698025 3038626304 3038626431 269
127698025 3038626560 3038626815 163
我的查询:
SELECT b.itemcode
FROM foo a, bar b
WHERE a.orderno BETWEEN b.startorderno AND b.endorderno;
答案 0 :(得分:8)
在Hive日志输出的最顶部,它表示"警告:随机加入JOIN [4] [表格a,b]在Stage' Stage-1 Mapred'是一种交叉产品。"
编辑: A'交叉产品'或笛卡尔积是无条件的连接,它返回' b'中的每一行。表格,对于' a'中的每一行表。所以,如果你举一个' a'是5行,' b'是10行,你得到产品,或者,5乘以10 = 50行返回。将会有很多行完全“无效”。对于一个或另一个表。
现在,如果你有一张桌子' a' 20,000行并将其加入另一个表格' b'在500,000行中,您要求SQL引擎向您返回一个数据集' a,b' 10,000,000,000行,然后对1000万行执行BETWEEN操作。
所以,如果你删掉了' b'行,你会发现你会得到比“a' - 在您的示例中,如果您可以过滤ip_logs表,表2,因为我猜测它的行数多于您的订单号表,它将减少执行时间。 结束编辑
通过不指定连接条件,您强制执行引擎处理笛卡尔积。它必须一遍又一遍地扫描所有表格。有10行,你就不会有问题。有了20k,你就会遇到几十个map / reduce wave。
尝试此查询:
SELECT b.itemcode
FROM foo a JOIN bar b on <SomeKey>
WHERE a.orderno BETWEEN b.startorderno AND b.endorderno;
但我无法确定您的模型允许加入的列。也许这个表达式的数据模型可以改进?可能只是我没有清楚地阅读样本。
无论哪种方式,您都需要在where子句之前过滤比较次数。我在Hive中完成此操作的其他方法是使用较小的数据集创建视图,并加入/匹配视图而不是原始表。