Presto

原创
2019/01/24 11:13
阅读数 1.6K

将时间戳转字符串

format_datetime(from_unixtime(time / 1000), 'yyyy-MM-dd HH:mm:ss')

多多使用WITH语句

使用Presto分析统计数据时,可考虑把多次查询合并为一次查询,用Presto提供的子查询完成。
这点和我们熟知的MySQL的使用不是很一样。例如:

WITH subquery_1 AS (
    SELECT a1, a2, a3 
    FROM Table_1 
    WHERE a3 between 20180101 and 20180131
),               /*子查询subquery_1,注意:多个子查询需要用逗号分隔*/
subquery_2 AS (
    SELECT b1, b2, b3
    FROM Table_2
    WHERE b3 between 20180101 and 20180131
)                /*最后一个子查询后不要带逗号,不然会报错。*/        
SELECT 
    subquery_1.a1, subquery_1.a2, 
    subquery_2.b1, subquery_2.b2
FROM subquery_1
    JOIN subquery_2
    ON subquery_1.a3 = subquery_2.b3;

 

查询SQL优化

  • 只选择使用必要的字段 

由于采用列式存储,选择需要的字段可加快字段的读取、减少数据量。避免采用*读取所有字段。

[GOOD]: SELECT time,user,host FROM tbl
[BAD]:  SELECT * FROM tbl
  • 过滤条件必须加上分区字段 

对于有分区的表,where语句中优先使用分区字段进行过滤。acct_day是分区字段,visit_time是具体访问时间

[GOOD]: SELECT time,user,host FROM tbl where acct_day=20171101
[BAD]:  SELECT * FROM tbl where visit_time=20171101
  • Group By语句优化 
    合理安排Group by语句中字段顺序对性能有一定提升。将Group By语句中字段按照每个字段distinct数据多少进行降序排列。
[GOOD]: SELECT GROUP BY uid, gender
[BAD]:  SELECT GROUP BY gender, uid
  • Order by时使用Limit 
    Order by需要扫描数据到单个worker节点进行排序,导致单个worker需要大量内存。如果是查询Top N或者Bottom N,使用limit可减少排序计算和内存压力。
[GOOD]: SELECT * FROM tbl ORDER BY time LIMIT 100
[BAD]:  SELECT * FROM tbl ORDER BY time
  • 使用Join语句时将大表放在左边 
    Presto中join的默认算法是broadcast join,即将join左边的表分割到多个worker,然后将join右边的表数据整个复制一份发送到每个worker进行计算。如果右边的表数据量太大,则可能会报内存溢出错误。
[GOOD] SELECT ... FROM large_table l join small_table s on l.id = s.id
[BAD] SELECT ... FROM small_table s join large_table l on l.id = s.id
  • 使用Rank函数代替row_number函数来获取Top N 
    在进行一些分组排序场景时,使用rank函数性能更好
[GOOD]
SELECT checksum(rnk)
FROM (
  SELECT rank() OVER (PARTITION BY l_orderkey, l_partkey ORDER BY l_shipdate DESC) AS rnk
  FROM lineitem
) t
WHERE rnk = 1

[BAD]
SELECT checksum(rnk)
FROM (
  SELECT row_number() OVER (PARTITION BY l_orderkey, l_partkey ORDER BY l_shipdate DESC) AS rnk
  FROM lineitem
) t
WHERE rnk = 1

字符串函数

下表列出了String函数。

序号 功能与说明
1 concat(string1,...,stringN)

连接给定的字符串

2 length(string)

返回给定字符串的长度

3 lower(string)

返回字符串的小写格式

4 upper(string)

返回给定字符串的大写格式

5 lpad(string,size,padstring)

给定字符串的左填充

6 ltrim(string)

从字符串中删除前导空格

7 replace(string, search, replace)

替换字符串值

8 reverse(string)

反转对字符串执行的操作

9 rpad(string,size,padstring)

给定字符串的正确填充

10 rtrim(string)

从字符串中删除尾随的空格

11 split(string, delimiter)

拆分分隔符上的字符串,并返回最大限制的大小数组

12 split_part(string, delimiter, index)

拆分分隔符上的字符串并返回字段索引

13 strpos(string,substring)

返回字符串中子字符串的起始位置

14 substr(string,start)

返回给定字符串的子字符串

15 substr(string,start,length)

返回具有特定长度的给定字符串的子字符串

16 trim(string)

从字符串中删除前导和尾随空格

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部