本文转载自:https://segmentfault.com/a/1190000013120454?utm_source=tag-newest

最近换了新工作,在数据处理方面,公司是用Presto连接各个业务部的数据库,直接上SQL处理数据。一度是不是很适应。经过一段时间的工作,有了些感觉,决定将遇到的一些坑记录下来。

Presto的是什么?优势是什么呢?从官方文档中我们了解到

Presto是一个分布式SQL查询引擎,用于查询分布在一个或多个不同数据源中的大数据集。
千万不要以为Presto可以解析SQL,那么Presto就是一个标准的数据库。
Presto被设计为数据仓库和数据分析产品:数据分析、大规模数据聚集和生成报表。这些工作经常通常被认为是线上分析处理操作。

所以说,当公司业务有跨库分析时(一般情况是,业务数据库分布在各个部门),一些数据需要配合其他部门的数据进行关联查询,这个时候可以考虑Presto。但是目前,对于MySQL统计查询在性能上有瓶颈。可考虑将数据按时间段归档到HDFS中,以提高统计效率。

如果需要对业务数据库进行较为实时的统计,而且不需要跨库操作的时候,建议还是直连数据库。

遇到过的问题

如何加快在Presto上的数据统计

很多的时候,在Presto上对数据库跨库查询,例如Mysql数据库。这个时候Presto的做法是从MySQL数据库端拉取最基本的数据,然后再去做进一步的处理,例如统计等聚合操作。
举个栗子:

SELECT count(id) FROM table_1 WHERE condition=1;

上面的SQL语句会分为3个步骤进行:

  1. Presto发起到Mysql数据库进行查询
SELECT id FROM table_1 WHERE condition=1;
  1. 对结果进行count计算
  2. 返回结果

所以说,对于Presto来说,其跨库查询的瓶颈是在数据拉取这个步骤。若要提高数据统计的速度,可考虑把Mysql中相关的数据表定期转移到HDFS中,并转存为高效的列式存储格式ORC。

所以定时归档是一个很好的选择,这里还要注意,在归档的时候我们要选择一个归档字段,如果是按日归档,我们可以用日期作为这个字段的值,采用yyyyMMdd的形式,例如20180123.

一般创建归档数据库的SQL语句如下:

CREATE TABLE IF NOT EXISTS table_1 (
id INTEGER,
........
partition_date INTEGER
)WITH ( format = 'ORC', partitioned_by = ARRAY['partition_date'] );

查看创建的库结构:

SHOW CREATE TABLE table_1; /*Only Presto*/

带有分区的表创建完成之后,每天只要更新分区字段partition_date就可以了,聪明的Presto就能将数据放置到规划好的分区了。

如果要查看一个数据表的分区字段是什么,可以下面的语句:

SHOW PARTITIONS FROM table_1 /*Only Presto*/

查询条件中尽量带上分区字段进行过滤

如果数据被规当到HDFS中,并带有分区字段。在每次查询归档表的时候,要带上分区字段作为过滤条件,这样可以加快查询速度。因为有了分区字段作为查询条件,就能帮助Presto避免全区扫描,减少Presto需要扫描的HDFS的文件数。

多多使用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; 

利用子查询,减少读表的次数,尤其是大数据量的表

具体做法是,将使用频繁的表作为一个子查询抽离出来,避免多次read。

只查询需要的字段

一定要避免在查询中使用 SELECT *这样的语句,换位思考,如果让你去查询数据是不是告诉你的越具体,工作效率越高呢。

对于我们的数据库而言也是这样,任务越明确,工作效率越高。

对于要查询全部字段的需求也是这样,没有偷懒的捷径,把它们都写出来。

Join查询优化

Join左边尽量放小数据量的表,而且最好是重复关联键少的表

字段名引用

Presto中的字段名引用使用双引号分割,这个要区别于MySQL的反引号`
当然,你可以不加这个双引号。

时间函数

对于timestamp,需要进行比较的时候,需要添加timestamp关键字,而MySQL中对timestamp可以直接进行比较。

/*MySQL的写法*/
SELECT t FROM a WHERE t > '2017-01-01 00:00:00'; 

/*Presto中的写法*/
SELECT t FROM a WHERE t > timestamp '2017-01-01 00:00:00';

MD5函数的使用

Presto中MD5函数传入的是binary类型,返回的也是binary类型,要对字符串进行MD5操作时,需要转换.

SELECT to_hex(md5(to_utf8('1212')));

不支持INSERT OVERWRITE语法

Presto中不支持insert overwrite语法,只能先delete,然后insert into。

ORC格式

Presto中对ORC文件格式进行了针对性优化,但在impala中目前不支持ORC格式的表,hive中支持ORC格式的表,所以想用列式存储的时候可以优先考虑ORC格式。

PARQUET格式

Presto目前支持parquet格式,支持查询,但不支持insert。

Presto上使用SQL遇到的一些坑的更多相关文章

  1. Ubuntu上配置SQL Server Always On Availability Group(Configure Always On Availability Group for SQL Server on Ubuntu)

    下面简单介绍一下如何在Ubuntu上一步一步创建一个SQL Server AG(Always On Availability Group),以及配置过程中遇到的坑的填充方法. 目前在Linux上可以搭 ...

  2. Configure Always On Availability Group for SQL Server on RHEL——Red Hat Enterprise Linux上配置SQL Server Always On Availability Group

    下面简单介绍一下如何在Red Hat Enterprise Linux上一步一步创建一个SQL Server AG(Always On Availability Group),以及配置过程中遇到的坑的 ...

  3. Configure Always On Availability Group for SQL Server on Ubuntu——Ubuntu上配置SQL Server Always On Availability Group

    下面简单介绍一下如何在Ubuntu上一步一步创建一个SQL Server AG(Always On Availability Group),以及配置过程中遇到的坑的填充方法. 目前在Linux上可以搭 ...

  4. 如何在linux服务器部署Rstudio server,配置ODBC远程访问win 服务器上的SQL server

    如何在linux服务器部署Rstudio server,配置ODBC后通过RODBC包远程访问SQL server 背景介绍:之前写过一篇文章,提到近期要部署Rstudio server(搭建数据分析 ...

  5. Linux上的SQL Server的起步

    我们知道,几个星期前,微软发布了在Linux上直接运行的SQL Server第一个公开CTP版本!因此,对我来说,是时候跨界在Linux上安装我的第一个SQL安装,这样的话,我就可以在Linux上折腾 ...

  6. 如何在64位系统上安装SQL Server 2000

    如何在64位系统上安装SQL Server 2000? 现在用SQL Server 2000数据库的人少了吧?大都是SQL Server 2005/2008了.不过还是有需求的,今天一朋友就让我在他的 ...

  7. 关于在页面上执行sql语句

    在页面上执行sql语句,首先在页面上顶一个文本域,让用户输入需要执行的sql语句. html代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...

  8. SQL Server on Ubuntu——Ubuntu上的SQL Server(全截图)

    本文从零开始一步一步介绍如何在Ubuntu上搭建SQL Server 2017,包括安装系统.安装SQL等相关步骤和方法(仅供测试学习之用,基础篇). 一.   创建Ubuntu系统(Create U ...

  9. SQL Server on Red Hat Enterprise Linux——RHEL上的SQL Server(全截图)

    本文从零开始一步一步介绍如何在Red Hat Enterprise Linux上搭建SQL Server 2017,包括安装系统.安装SQL等相关步骤和方法(仅供测试学习之用,基础篇). 一.   创 ...

随机推荐

  1. python基于django编写api+前端后端分离

    有用 https://segmentfault.com/a/1190000016049962#articleHeader2 python的前后端分离(一):django+原生js实现get请求 htt ...

  2. Python3学习之路~6.5 私有属性和私有方法

    属性分为静态属性和动态属性,静态属性就是变量,动态属性就是方法.但是一般我们说的属性就是变量,方法就是方法.私有属性/方法就是外面访问不了,只有自己能够访问的属性/方法.如何将属性和方法分别变成私有属 ...

  3. wx鼠标拖动事件

    #coding:UTF- import wx app = wx.App() def dragEVT(event): if event.ButtonDown(): panel1.SetPosition( ...

  4. easyui——validType属性值

  5. MongoDB--连接客户端和服务

    直接在官网上下载好编译好的二进制文件,安装.这里安装在c盘了 安装图形界面: 打开文件进入C:\Program Files\MongoDB\Server\3.4\bin 在bin目录下: 客服端和服务 ...

  6. (已解决)Xcode 运行报错: clang: error: unknown argument: '-websockets'

    报错内容: 解决办法:

  7. Solaris 10主机名和IP地址步骤

    1.修改主机名: hostname newname vi /etc/hosts vi /etc/hostname.e1000g0 vi /etc/nodename init 6 #重启 --confi ...

  8. 日期条控件 DateFieldControl

    日期条控件 书:163 <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns ...

  9. python知识补足

    1.class的init功能,初始化class,给出一些初始值 __init__可以理解成初始化class的变量,取自英文中initial 最初的意思.可以在运行时,给初始值附值, class Cal ...

  10. 突然pom.xml中引用的jar包出错。

    在你的本地仓库中,用window搜索包含.lastupdated的文件,全部删除!然后再去项目上maven ------update project