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 性能优化点的主要内容,如果未能解决你的问题,请参考以下文章