演讲:对 2000 多亿条数据做一次 group by 需要多久?

http://2017.qconbeijing.com/presentation/646?utm_source=weibo&utm_medium=infoq&utm_campaign=yj

专题演讲嘉宾 :易杰
腾讯社交与效果广告部检索系统组主管

    在腾讯工作 10 年,一直从事效果广告的研发工作,对互联网广告及精准推广有较深理解,具备优秀的互联网海量运营经验。
    现负责腾讯社交广告平台百亿级广告引擎系统,OLAP 系统 PivotEngine 等。

SPA 自研 PivotEngine 可以在 2 秒内完成。
数据是很多业务的核心驱动力之一。对于“SPA”这样的广告业务,更是如此。几十亿用户,每天几百亿次曝光,都产生大量的数据。对这些数据进行透视分析,发现其中蕴含的一些高层宏观信息,对于广告主以及我们自己的产品、运营、策略开发等人员的决策都能提供指导和帮助。
比如广告主投放一条广告,他想了解浏览了其广告的这批用户的年龄是个什么样的分布,更进一步地,其想对比一下曝光用户和有点击行为的用户,比如曝光中 25 岁的用户占比是 10%,但是点击中 25 岁的用户占比却高达 15%。
对于运营来说,他们可能想了解一段时间整个系统中获得不同曝光次数的用户的占比、点击率、产生的收入等。比如最近 10 天内产生 1 次曝光的用户的数量、平均点击率、收入,2 次曝光用户的数量、平均点击率、收入等。
对于广告主的这种简单需求,通过 SQL 可以这样得到结果:

select age, count(*) from log where advertiser_id=xxx group by age

对于后面那种按曝光量聚合统计的需求来说,假设每条曝光日志作为一条基本的数据,那么 sql 大概是如下这种形式的两层 GROUP BY 嵌套查询:

SELECT
    exposure_num,
    COUNT(*) as user_num,
    SUM(sum_click) / SUM(exposure_num) as click_rate,
    SUM(sum_cost) AS total_cost
FROM
    (SELECT
         qq,
         COUNT(*) AS exposure_num,
         SUM(click_count) AS sum_click,
         SUM(cost) AS sum_cost
     FROM
         log_table
     GROUP BY qq) temp_table
GROUP BY exposure_num;

如果只有几十万或几百万条数据,也许 mysql 就可以很好的解决这个问题。但是当数据规模达到几十亿、几百亿甚至上千亿时,mysql 就无法处理了。此外 mysql 一行数据在一列上只能取一个值,但是对于一个用户来说,其某个属性可能是多值,比如用户的商业兴趣,会有多个值。这时按照“商业兴趣”这一列进行 group by,mysql 也无法或者不方便处理。
为了高效低成本地支持这种简单的“过滤-聚合”模式,也即“where-group by-(count|sum|avg) ”这种模式的查询分析请求,当然易用也是非常重要的,我们自研了一套在线查询分析引擎“PivotEngine”。

原文地址:https://www.cnblogs.com/scotth/p/6824121.html