想象一下一个博客,其中每个事件都归因于多个维度(siteID,countryID,pageID等),并且还有一个访客ID:
eventID | siteID | countryID | pageID | visitorID
目标是为每个维度组合计算唯一身份访问者,包括总计(即多维数据集)。它可以表示为以下Spark SQL查询:
SELECT
COUNT(DISTINCT(visitorID))
FROM weblog
GROUP BY siteID, countryID, pageID WITH CUBE
假设所有维度字段都具有相对较高的基数,Spark可以有效地完成这种聚合,因为每个维度组合将接收相对较少数量的访问者ID。
然而,CUBE操作会创建与
等分组相对应的繁重任务... GROUP BY siteID, countryID
... GROUP BY siteID
etc.
这些任务会收到非常多的ID(计算总计的任务会接收整个日志中的所有ID)。似乎Spark 2.2无法并行化,因此作业运行时受这些长时间运行的任务的限制。
如何优化此类查询?
答案 0 :(得分:0)
简短的回答是不要使用COUNT(DISTINCT(_))
。你不能吃蛋糕然后吃。您可以获得精确的结果,这可能会导致偏差和失败,或者具有有限精度和可预测性能的合理近似值。
而是使用草图使用近似计数。
SELECT approx_count_distinct(visitorID)
FROM ...
GROUP BY ... WITH CUBE