Presto 性能优化点

1、指定需要返回的字段

[GOOD]: SELECT time,user,host FROM tbl
[BAD]: SELECT * FROM tbl

2、合理设置分区字段

当过滤条件作用在分区字段上面时,可以减少数据扫描的范围,有效提升查询性能。

这个需要结合OLAP业务进行考虑,将常规过滤字段设置成分区字段,例如:订单时间(适用于时间范围的统计分析)、租户id(适用于多租户平台中各个租户的统计分析)等。

3、group by的时候考虑统计字段基数

字段基数:是指某字段拥有不同值的个数。例如:性别字段的基数一般是2,月份字段的基数是12。

group by的时候需要将基数大的字段放在前面

[GOOD]: SELECT GROUP BY uid, gender
[BAD]: SELECT GROUP BY gender, uid

如果group by的字段是数值型,将比字符型更节省内存使用空间。

4、order by 和 limit 配合使用(topN)

[GOOD]: SELECT * FROM tbl ORDER BY time LIMIT 100
[BAD]: SELECT * FROM tbl ORDER BY time

order by 需要将所有数据放到一个worker中进行排序,这将消耗大量的内存空间。配合limit使用将有效减小内存空间的使用,提升查询性能。

topN 可以只需使用size=N的优先级队列即可完成,这只占用非常小的内存空间。

5、使用近似统计的功能(approximate aggregate functions)

presto提供了一些近似统计的函数,这显著提高了查询统计性能。当然,这是以牺牲准确性为代价的。

例如:approx_distinct函数,我们将得到一个误差在2.3%的近似值。

SELECT
approx_distinct(user_id)
FROM
access
WHERE
TD_TIME_RANGE(time,
TD_TIME_ADD(TD_SCHEDULED_TIME(), '-1d', 'PDT'),
TD_SCHEDULED_TIME())

上面事例表示:查询前一天不同访问用户的数量(UV)。

6、使用regexp_like

SELECT
...
FROM
access
WHERE
method LIKE '%GET%' OR
method LIKE '%POST%' OR
method LIKE '%PUT%' OR
method LIKE '%DELETE%'

使用regexp_like优化处理:

SELECT
...
FROM
access
WHERE
regexp_like(method, 'GET|POST|PUT|DELETE')

7、join的时候把大表放在左边

presto在join的时候采用的是broadcast join,意思是右边的表将全部数据send到各个worker和左边的表(每个worker持有一部分左边表的数据)进行关联查询。

例如:订单表和用户表,需要根据用户维度对订单的某些度量进行统计分析。一般情况下,订单的数据量远大于用户的数据量,因此order left join customer。

如果有10个worker,那么10个worker将各持有1/10的订单数据(假设数据分布均匀),然后将所有用户数据send到10个worker上进行join操作。

有的时候如果右边的表确实很大,那么有可能遇到“ERROR:Exceeded max memory xxGB”,这个xxGB是配置文件中指定的每次查询worker使用的最大内存空间。超过这个阈值将报这个异常信息。这种情况要不就调整参数,要不就使用“distributed hash join”。

参考:

1)Presto Performance Tuning Tips

猜你喜欢

转载自www.cnblogs.com/huangfox/p/9568934.html