更高效的查询以避免 Hive 中的 OutOfMemoryError
More efficient query to avoid OutOfMemoryError in Hive
我在 Hive 中遇到异常:
java.lang.OutOfMemoryError: GC overhead limit exceeded.
在搜索中我发现这是因为所有 CPU 过程中 98% 的时间都将用于垃圾收集(不管那是什么意思?)。我的问题的核心在我的查询中吗?我是否应该以不同的方式编写以下内容以避免此类问题?
我正在计算在给定时间段内有多少特定 phone 类型具有活跃的 'Use'。有没有办法以不同的方式执行此逻辑,这会 运行 更好?
select count(a.imei)
from
(Select distinct imei
from pingdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
and ((SUBSTR(imei,12,2) = "04") or (SUBSTR(imei,12,2) = "05")) ) a
join
(SELECT distinct imei
FROM eventdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
AND event = "Use" AND clientversion like '3.2%') b
on a.imei=b.imei
谢谢
为了提高性能,通过查看您的查询:我将按 yyyy, mm, dd
或 imei
的前两位数对配置单元表进行分区,您必须根据根据您查询这些表和数据量的需要。但我会投票给 yyyy, mm, dd
,这会给你带来巨大的性能改进。见 improving-query-performance-using-partitioning
但是现在,这应该会给您带来一些改进:
Select count(distinct(pd.imei))
from pingdata pd join eventdata ed on pd.imei=ed.imei
where
TO_DATE(pd.timestamp) between '2016-06-01' AND '2016-07-17'
and pd.timestamp=ed.pd.timestamp
and SUBSTR(pd.imei,12,2) in ('04','05')
and ed.event = 'Use' AND ed.clientversion like '3.2%';
如果 TO_DATE(timestamp)
值在同一天插入,换句话说,如果日期的两个值相同,则应排除 and pd.timestamp=ed.pd.timestamp
条件。
Select count(distinct(pd.imei))
from pingdata pd join eventdata ed on pd.imei=ed.imei
where
TO_DATE(pd.timestamp) between '2016-06-01' AND '2016-07-17'
and SUBSTR(pd.imei,12,2) in ('04','05')
and ed.event = 'Use' AND ed.clientversion like '3.2%';
尝试 运行 两个查询并比较结果。如果您觉得这有帮助,请告诉我们不同之处。
在加入每个数据集之前对它们应用 distinct 更安全,因为加入非唯一键会复制数据。
我建议按 to_date(timestamp) 字段 (yyyy-MM-dd) 对您的数据集进行分区,以便根据您的 where 子句进行分区修剪(检查是否有效)。如果数据集太大并且包含大量事件 <> 'Use' 的数据,也可以按事件字段进行分区。
了解它在哪个阶段失败很重要。还要研究异常。如果它在映射器上失败,那么你应该优化你的子查询(如我提到的那样添加分区)。如果它在 reducer (join) 上失败,那么你应该以某种方式改进 join(尝试减少每个 reducer 的字节数:
set hive.exec.reducers.bytes.per.reducer=67108864;
或什至更少)如果它在 writer 上失败(OrcWriter 然后尝试通过 imei 的 substr 将分区添加到输出 table 和'distribute by substr(imei...)` 在查询结束以减轻减速器的压力)。
或者添加更多低基数和均匀分布的列,以在更多 reducer 之间均匀分布数据:
distribute by substr(imei...), col2
确保分区列在分配依据中。这将减少每个 reducer 写入的文件数量并有助于摆脱 OOM
我在 Hive 中遇到异常:
java.lang.OutOfMemoryError: GC overhead limit exceeded.
在搜索中我发现这是因为所有 CPU 过程中 98% 的时间都将用于垃圾收集(不管那是什么意思?)。我的问题的核心在我的查询中吗?我是否应该以不同的方式编写以下内容以避免此类问题?
我正在计算在给定时间段内有多少特定 phone 类型具有活跃的 'Use'。有没有办法以不同的方式执行此逻辑,这会 运行 更好?
select count(a.imei)
from
(Select distinct imei
from pingdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
and ((SUBSTR(imei,12,2) = "04") or (SUBSTR(imei,12,2) = "05")) ) a
join
(SELECT distinct imei
FROM eventdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
AND event = "Use" AND clientversion like '3.2%') b
on a.imei=b.imei
谢谢
为了提高性能,通过查看您的查询:我将按 yyyy, mm, dd
或 imei
的前两位数对配置单元表进行分区,您必须根据根据您查询这些表和数据量的需要。但我会投票给 yyyy, mm, dd
,这会给你带来巨大的性能改进。见 improving-query-performance-using-partitioning
但是现在,这应该会给您带来一些改进:
Select count(distinct(pd.imei))
from pingdata pd join eventdata ed on pd.imei=ed.imei
where
TO_DATE(pd.timestamp) between '2016-06-01' AND '2016-07-17'
and pd.timestamp=ed.pd.timestamp
and SUBSTR(pd.imei,12,2) in ('04','05')
and ed.event = 'Use' AND ed.clientversion like '3.2%';
如果 TO_DATE(timestamp)
值在同一天插入,换句话说,如果日期的两个值相同,则应排除 and pd.timestamp=ed.pd.timestamp
条件。
Select count(distinct(pd.imei))
from pingdata pd join eventdata ed on pd.imei=ed.imei
where
TO_DATE(pd.timestamp) between '2016-06-01' AND '2016-07-17'
and SUBSTR(pd.imei,12,2) in ('04','05')
and ed.event = 'Use' AND ed.clientversion like '3.2%';
尝试 运行 两个查询并比较结果。如果您觉得这有帮助,请告诉我们不同之处。
在加入每个数据集之前对它们应用 distinct 更安全,因为加入非唯一键会复制数据。
我建议按 to_date(timestamp) 字段 (yyyy-MM-dd) 对您的数据集进行分区,以便根据您的 where 子句进行分区修剪(检查是否有效)。如果数据集太大并且包含大量事件 <> 'Use' 的数据,也可以按事件字段进行分区。
了解它在哪个阶段失败很重要。还要研究异常。如果它在映射器上失败,那么你应该优化你的子查询(如我提到的那样添加分区)。如果它在 reducer (join) 上失败,那么你应该以某种方式改进 join(尝试减少每个 reducer 的字节数:
set hive.exec.reducers.bytes.per.reducer=67108864;
或什至更少)如果它在 writer 上失败(OrcWriter 然后尝试通过 imei 的 substr 将分区添加到输出 table 和'distribute by substr(imei...)` 在查询结束以减轻减速器的压力)。
或者添加更多低基数和均匀分布的列,以在更多 reducer 之间均匀分布数据:
distribute by substr(imei...), col2
确保分区列在分配依据中。这将减少每个 reducer 写入的文件数量并有助于摆脱 OOM