Presto 性能优化点

Posted huangfox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

以上是关于Presto 性能优化点的主要内容,如果未能解决你的问题,请参考以下文章

Presto在字节跳动的内部实践与优化

Presto在字节跳动的内部实践与优化

对于iOS性能优化的一点看法

性能优化: http 请求的过程及潜在的性能优化点

Android性能优化之被忽视的优化点

Android性能优化之被忽视的优化点