优化多表连接的配置单元查询

Posted

技术标签:

【中文标题】优化多表连接的配置单元查询【英文标题】:optimize hive query for multitable join 【发布时间】:2014-03-26 17:23:56 【问题描述】:
INSERT OVERWRITE TABLE result
SELECT /*+ STREAMTABLE(product) */
i.IMAGE_ID, 
p.PRODUCT_NO,
p.STORE_NO,
p.PRODUCT_CAT_NO,
p.CAPTION,
p.PRODUCT_DESC,
p.IMAGE1_ID,
p.IMAGE2_ID, 
s.STORE_ID, 
s.STORE_NAME, 
p.CREATE_DATE, 
CASE WHEN custImg.IMAGE_ID is NULL THEN 0 ELSE 1 END, 
CASE WHEN custImg1.IMAGE_ID is NULL THEN 0 ELSE 1 END, 
CASE WHEN custImg2.IMAGE_ID is NULL THEN 0 ELSE 1 END
FROM image i  
JOIN PRODUCT p ON i.IMAGE_ID = p.IMAGE1_ID
JOIN PRODUCT_CAT pcat ON p.PRODUCT_CAT_NO = pcat.PRODUCT_CAT_NO
JOIN STORE s ON p.STORE_NO = s.STORE_NO
JOIN STOCK_INFO si ON si.STOCK_INFO_ID = pcat.STOCK_INFO_ID 
LEFT OUTER JOIN CUSTOMIZABLE_IMAGE custImg ON i.IMAGE_ID = custImg.IMAGE_ID 
LEFT OUTER JOIN CUSTOMIZABLE_IMAGE custImg1 ON p.IMAGE1_ID = custImg1.IMAGE_ID 
LEFT OUTER JOIN CUSTOMIZABLE_IMAGE custImg2 ON p.IMAGE2_ID = custImg2.IMAGE_ID;

我有一个连接查询,我正在连接巨大的表,我正在尝试优化这个配置单元查询。以下是有关表格的一些事实

图像表有 60m 行, 产品表有 1b 行, product_cat 有 1000 行, store 有 1m 行, stock_info 有 100 行, Customized_image 有 200k 行。

一个产品可以有一个或两个图像(image1 和 image2)并且产品级别信息只存储在产品表中。我尝试将与产品的联接移至底部,但我不能,因为所有其他以下联接都需要产品表中的数据。

这是我迄今为止尝试过的, 1. 我提示 hive 将流产品表作为其最大的表 2. 我将表(在创建表期间)分成 256 个桶(在 image_id 上),然后进行连接 - 没有给我任何显着的性能提升 3. 将输入格式从 textfile(gzip files) 更改为序列文件,以便它可以拆分,因此如果 hive 想要运行更多映射器,则可以运行更多映射器

这是来自 hive 控制台的一些关键日志。我在 aws 中运行了这个配置单元查询。谁能帮我理解这里的主要瓶颈?此作业仅处理实际数据的子集。

Stage-14 is selected by condition resolver.
Launching Job 1 out of 11
Number of reduce tasks not specified. Estimated from input data size: 22
In order to change the average load for a reducer (in bytes):
  set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
  set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
  set mapred.reduce.tasks=<number>
Kill Command = /home/hadoop/bin/hadoop job  -kill job_201403242034_0001
Hadoop job information for Stage-14: number of mappers: 341; number of reducers: 22
2014-03-24 20:55:05,709 Stage-14 map = 0%,  reduce = 0%
.
2014-03-24 23:26:32,064 Stage-14 map = 100%,  reduce = 100%, Cumulative CPU 34198.12 sec
MapReduce Total cumulative CPU time: 0 days 9 hours 29 minutes 58 seconds 120 msec
.
2014-03-25 00:33:39,702 Stage-30 map = 100%,  reduce = 100%, Cumulative CPU 20879.69 sec
MapReduce Total cumulative CPU time: 0 days 5 hours 47 minutes 59 seconds 690 msec
.
2014-03-26 04:15:25,809 Stage-14 map = 100%,  reduce = 100%, Cumulative CPU 3903.4 sec
MapReduce Total cumulative CPU time: 0 days 1 hours 5 minutes 3 seconds 400 msec
.
2014-03-26 04:25:05,892 Stage-30 map = 100%,  reduce = 100%, Cumulative CPU 2707.34 sec
MapReduce Total cumulative CPU time: 45 minutes 7 seconds 340 msec
.
2014-03-26 04:45:56,465 Stage-2 map = 100%,  reduce = 100%, Cumulative CPU 3901.99 sec
MapReduce Total cumulative CPU time: 0 days 1 hours 5 minutes 1 seconds 990 msec
.
2014-03-26 04:54:56,061 Stage-26 map = 100%,  reduce = 100%, Cumulative CPU 2388.71 sec
MapReduce Total cumulative CPU time: 39 minutes 48 seconds 710 msec
.
2014-03-26 05:12:35,541 Stage-4 map = 100%,  reduce = 100%, Cumulative CPU 3792.5 sec
MapReduce Total cumulative CPU time: 0 days 1 hours 3 minutes 12 seconds 500 msec
.
2014-03-26 05:34:21,967 Stage-5 map = 100%,  reduce = 100%, Cumulative CPU 4432.22 sec
MapReduce Total cumulative CPU time: 0 days 1 hours 13 minutes 52 seconds 220 msec
.
2014-03-26 05:54:43,928 Stage-21 map = 100%,  reduce = 100%, Cumulative CPU 6052.96 sec
MapReduce Total cumulative CPU time: 0 days 1 hours 40 minutes 52 seconds 960 msec

MapReduce Jobs Launched: 

Job 0: Map: 59  Reduce: 18   Cumulative CPU: 3903.4 sec     HDFS Read: 37387 HDFS Write: 12658668325 SUCCESS
Job 1: Map: 48              Cumulative CPU: 2707.34 sec   HDFS Read: 12658908810 HDFS Write: 9321506973 SUCCESS
Job 2: Map: 29  Reduce: 10   Cumulative CPU: 3901.99 sec   HDFS Read: 9321641955 HDFS Write: 11079251576 SUCCESS
Job 3: Map: 42              Cumulative CPU: 2388.71 sec   HDFS Read: 11079470178 HDFS Write: 10932264824 SUCCESS
Job 4: Map: 42  Reduce: 12   Cumulative CPU: 3792.5 sec     HDFS Read: 10932405443 HDFS Write: 11812454443 SUCCESS
Job 5: Map: 45  Reduce: 13   Cumulative CPU: 4432.22 sec   HDFS Read: 11812679475 HDFS Write: 11815458945 SUCCESS
Job 6: Map: 42              Cumulative CPU: 6052.96 sec   HDFS Read: 11815691155 HDFS Write: 0 SUCCESS
Total MapReduce CPU Time Spent: 0 days 7 hours 32 minutes 59 seconds 120 msec
OK

在 Hive 中查询仍然需要超过 5 个小时,而在 RDBMS 中只需要 5 个小时。我需要一些帮助来优化这个查询,以便它执行得更快。有趣的是,当我用 4 个大型核心实例运行任务时,与运行 3 个大型实例核心实例相比,所用时间仅缩短了 10 分钟。但是当我使用 3 个 med 核心运行任务时,需要多花 1 小时 10 分钟。

这让我想到了一个问题,“对于这种复杂的连接,Hive 是否是正确的选择”?

【问题讨论】:

您的表是否分区? 不,它现在没有分区。我读到分区有助于查询哪里,但没有读到任何关于连接查询的内容。无论如何,我打算尝试使用 image_id 对表进行分区。 是的..一旦分区,您可以在多连接查询中使用各种选项,如 DISTRIBUTE BYCLUSTER BY 以提高性能。 【参考方案1】:

我怀疑瓶颈只是在排序您的产品表,因为它似乎比其他表大得多。我认为使用 Hive 连接超过一定大小的表变得站不住脚,仅仅是因为它们需要排序。

有优化排序的参数,比如io.sort.mb,可以尝试设置,让更多的排序发生在内存中,而不是溢出到磁盘,重读重排序。查看溢出记录的数量,看看这是否比您的输入大得多。有多种方法可以优化排序。它还可能有助于将您的查询分解为多个子查询,这样就不必一次进行太多排序。

对于 stock_info 和 product_cat 表,您可以将它们保存在内存中,因为它们非常小(查看 Brickhouse 中的 'distributed_map' UDF (https://github.com/klout/brickhouse/blob/master/src/main/java/brickhouse/udf/dcache/DistributedMapUDF.java) 对于自定义图像,您可以使用bloom过滤器,如果有一些误报不是一个真正的大问题。

要完全删除连接,也许您可​​以将图像信息存储在 HBase 之类的 keystone 数据库中以进行查找。 Brickhouse 也有用于 HBase 的 UDF,例如 hbase_get 和 base_cached_get。

【讨论】:

我会尝试您建议的排序设置。您是否建议在一个查询中加入产品和图像,并使用某种内存方法加入其余的?我认为 hive 已经做了 MapJoin(对于较小的表),这是一个内存连接,不是吗?我试图通过查看 aws 的配置单元控制台输出来找到瓶颈。我无法从中推断出任何有用的信息。我将使用该信息编辑问题,希望有人可以帮助我解决瓶颈。

以上是关于优化多表连接的配置单元查询的主要内容,如果未能解决你的问题,请参考以下文章

如何优化多表连接视图以获得更快的响应?

MySQL调优--05---多表查询优化子查询优化 ORDER BY优化GROUP BY优化分页查询优化

多表关联查询语法?

oracle 中多表连接如何用

mysql 数据操作 多表查询 目录

MySQL多表连接查询