我使用 AWS-EMR运行我的 Hive 查询,我在运行 Hive 版本 0.13.1 时遇到了性能问题。
较新版本的 hive 运行 10 行数据大约需要 5 分钟。但是 230804 行的相同脚本需要 2 天并且仍在运行。我应该如何分析和解决问题?
示例数据:
表 1:
hive> describe foo;
OK
orderno string
Time taken: 0.101 seconds, Fetched: 1 row(s)
Sample data for 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)
Sample data for Table 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;
最佳答案
在 Hive 日志输出的最顶部,它指出“警告:阶段‘Stage-1 Mapred’中的 Shuffle Join JOIN[4][Tables a, b] 是叉积。”
编辑: “叉积”或笛卡尔积是没有条件的连接,它返回“b”表中的每一行,对应“a”表中的每一行。因此,如果您以“a”为 5 行,“b”为 10 行为例,您将得到乘积,即 5 乘以 10 = 返回 50 行。对于一个或另一个表,将有很多行完全为“空”。
现在,如果您有一个包含 20,000 行的表“a”,并将其连接到另一个包含 500,000 行的表“b”,则您要求 SQL 引擎返回给您一个包含 10,000,000,000 行的数据集“a,b” , 然后对1000万行进行BETWEEN操作。
因此,如果您减少“b”行的数量,您会发现您将获得比“a”更多的好处 - 在您的示例中,如果您可以过滤 ip_logs 表,表 2,因为我正在猜测它的行数比您的订单号表多,它将减少执行时间。 结束编辑
您通过不指定联接条件来强制执行引擎处理笛卡尔积。它必须一遍又一遍地扫描整个表。有 10 行,你不会有问题。使用 20k,您将遇到数十个 map/reduce 浪潮。
试试这个查询:
SELECT b.itemcode
FROM foo a JOIN bar b on <SomeKey>
WHERE a.orderno BETWEEN b.startorderno AND b.endorderno;
但我无法确定您的模型允许加入的列。也许可以改进此表达式的数据模型?可能只是我没有看清楚样本。
无论哪种方式,您都需要在 where 子句之前过滤比较次数。我在 Hive 中完成此操作的其他方法是使用较小的数据集创建 View ,然后加入/匹配 View 而不是原始表。
关于hadoop - Hive 版本 0.13.1 中的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27900760/