在自我加入上缓慢处理配置单元

时间:2014-08-26 08:22:00

标签: hadoop timestamp hive query-optimization

我有一个hive表,其中我正在进行自我加入并在ip的基础上加入并区分名称并使用unix_timestamp将其转换为秒并减去时间来减去字符串格式的日期。但是这需要很多时间。

Create table t1 (a_name string,a_Code bigint,a_Time string,
a_Ipaddress string, b_name string,b_Code bigint,b_TIME string,b_Ipaddress
string,date1 string) 
STORED as RCFILE;

INSERT INTO TABLE NETWORK_Sharing 
SELECT n1.a_name,n1.a_Code,n1.a_TIME ,n1.a_Ipaddress,n2.b_name ,n2.b_Code,n2.b_TIME,
n2.b_Ipaddress,n1.date1 from t n1 JOIN t n2
ON (n1.a_Ipaddress=n2.b_Ipaddress) 
where n1.a_name <> n2.b_name AND
(unix_timestamp(n1.a_TIME,'yyyy-MM-dd HH:mm:ss') -
unix_timestamp(n2.b_TIME,'yyyy-MM-dd HH:mm:ss')) <= 300 AND
(unix_timestamp(n1.TIME,'yyyy-MM-dd HH:mm:ss') -
unix_timestamp(n2.TIME,'yyyy-MM-dd HH:mm:ss')) >= 0;

1 个答案:

答案 0 :(得分:1)

如果可能的话,我会避免自我加入,并使用collect来执行聚合而不是连接。查看此博客文章,其中讨论了类似的用例(http://brickhouseconfessions.wordpress.com/2013/03/05/use-collect-to-avoid-the-self-join/

在您的情况下,您基本上想要查看两个事件是否同时发生,因此可能有点棘手。怎么样的

CREATE TABLE t1 
AS
SELECT Ipaddress, 
     cast( TIME/300 as bigint ) as EVENT_TIME_BUCKET,
     collect( name ) as NAMES,
     collect( code ) as CODES
     collect( TIME ) as TIMES
FROM t
GROUP BY 
   IpAddress, cast(TIME/300 as bigint)
HAVING count(*) > 1;

我想你可能希望有一个600的更大时间段,具体取决于你的用例,  并消除不符合您标准的行。 (比如  在哪里! (size(TIMES)== 2 AND array_index(TIMES,1) - array_index(TIMES,0)&gt; 300) )但您的实际查询或阈值将取决于您的数据集。