我的hive中有两个观点
+------------+
| Table_1 |
+------------+
| hash |
| campaignId |
+------------+
+-----------------+
| Table_2 |
+-----------------+
| campaignId |
| accountId |
| parentAccountID |
+-----------------+
现在我必须抓取' Table_1'通过accountId&过滤的数据parentAccountID,我为此编写了以下查询:
SELECT /*+ MAPJOIN(T2) */ T1.hash, COUNT(T1.campaignId) num_campaigns
FROM Table_1 T1
JOIN Table_2 T2 ON T1.campaignId = T2.campaignId
WHERE (T2.accountId IN ('aid1', 'aid2') OR T2.parentAccountID IN ('aid1', 'aid2')
GROUP BY T1.hash
此查询正在运行但速度很慢。有没有更好的替代方案(JOIN)?
我正在通过spark从卡夫卡读到Table_1
幻灯片持续时间为5秒
窗口持续时间为2分钟
虽然Table_2在RDBMS中,但是火花正在通过jdbc读取,而且它有4500条记录。
每隔5秒,kafka以CSV格式记录大约2K记录 我需要在5秒内处理数据,但目前需要8到16秒。
根据建议:
但仍然没有改善。
注意: 如果我删除了窗口持续时间,那么该过程会在一段时间内执行。可能是因为要处理的数据较少。但这不是要求。
答案 0 :(得分:0)
使用正确的索引,以下内容可以更快:
iframe
第一个可以考虑SELECT T1.*
FROM Table_1 T1 JOIN
Table_2 T2
ON T1.campaignId = T2.campaignId
WHERE T2.accountId IN ('aid1', 'aid2')
UNION ALL
SELECT T1.*
FROM Table_1 T1 JOIN
Table_2 T2
ON T1.campaignId = T2.campaignId
WHERE T2.parentAccountID IN ('aid1', 'aid2') AND
T2.accountId NOT IN ('aid1', 'aid2') ;
上的索引和Table_2(accountId, campaignId)
上的第二个索引。
答案 1 :(得分:0)
由于这是我们所讨论的Hive,您需要关注的不仅仅是传统的DBMS。
答案 2 :(得分:0)
如果T2过滤小到足以适合内存,请尝试重写查询并将过滤器移动到子查询中,并查看是否将在mapper上执行连接。此外,您不需要T2中的列,可以使用左半连接而不是内连接:
set hive.cbo.enable=true;
set hive.auto.convert.join=true;
SELECT T1.*
FROM Table_1 T1
LEFT SEMI JOIN
(select campaignId from Table_2 T2
where T2.accountId IN ('aid1', 'aid2')
OR T2.parentAccountID IN ('aid1', 'aid2')
) T2 ON T1.campaignId = T2.campaignId
;
答案 3 :(得分:0)
我建议您使用本机Spark转换而不是HiveSQL:
1.将表2中的数据(RDBMS)读入RDD&把它放在缓存中 例如:
rddTbl1.map(campaignIdKey, (accountId, parentAccountId)) //filter out before getting into RDD if needed
rddTbl2.cache()
2.现在读取Table_1流(Kafka)
//get campaigns of relevant account & parentaccountid
val rddTbl2_1 = rddTbl2.filter(x => x._2._1.equals("aid1") || x._2._1.equals("aid2") || x._2._2.equals("aid1") || x._2._2.equals("aid2"))
dstream.foreachRDD{ rddTbl1 =>
rddTbl1.map(x => x._2.split(",")).
map(x => (x(1), x(2)). //campaignId, hash
join(rddTbl2_1).
map(x => (x._2._1, 1)). //get (hash,1)
reduceByKey(_+_).
foreach(println) //save it if needed
}
答案 4 :(得分:0)
确定..
这是我最终做的。
我创建了表2的哈希 然后通过使用广播变量,我将该数据传递给每个节点。
这让我省去了加入的麻烦。
谢谢大家的时间和帮助。 快乐的编码:)