Presto上使用SQL遇到的一些坑

2021-09-14 04:09:37 字數 3253 閱讀 9776

最近換了新工作,在資料處理方面,公司是用presto連線各個業務部的資料庫,直接上sql處理資料。一度是不是很適應。經過一段時間的工作,有了些感覺,決定將遇到的一些坑記錄下來。
presto的是什麼?優勢是什麼呢?從官方文件中我們了解到

presto是乙個分布式sql查詢引擎,用於查詢分布在乙個或多個不同資料來源中的大資料集。

千萬不要以為presto可以解析sql,那麼presto就是乙個標準的資料庫。

presto被設計為資料倉儲和資料分析產品:資料分析、大規模資料聚集和生成報表。這些工作經常通常被認為是線上分析處理操作。

所以說,當公司業務有跨庫分析時(一般情況是,業務資料庫分布在各個部門),一些資料需要配合其他部門的資料進行關聯查詢,這個時候可以考慮presto。但是目前,對於mysql統計查詢在效能上有瓶頸。可考慮將資料按時間段歸檔到hdfs中,以提高統計效率。

如果需要對業務資料庫進行較為實時的統計,而且不需要跨庫操作的時候,建議還是直連資料庫。

很多的時候,在presto上對資料庫跨庫查詢,例如mysql資料庫。這個時候presto的做法是從mysql資料庫端拉取最基本的資料,然後再去做進一步的處理,例如統計等聚合操作。

舉個栗子:

select count(id) from table_1 where condition=1;
上面的sql語句會分為3個步驟進行:

presto發起到mysql資料庫進行查詢

select id from table_1 where condition=1;
對結果進行count計算

返回結果

所以說,對於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的檔案數。

使用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左邊盡量放小資料量的表,而且最好是重複關聯鍵少的表

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';

presto中md5函式傳入的是binary型別,返回的也是binary型別,要對字串進行md5操作時,需要轉換.

select to_hex(md5(to_utf8('1212')));
presto中不支援insert overwrite語法,只能先delete,然後insert into。

presto中對orc檔案格式進行了針對性優化,但在impala中目前不支援orc格式的表,hive中支援orc格式的表,所以想用列式儲存的時候可以優先考慮orc格式。

presto目前支援parquet格式,支援查詢,但不支援insert。

Presto上使用SQL遇到的一些坑

presto的是什麼?優勢是什麼呢?從官方文件中我們了解到 presto是乙個分布式sql查詢引擎,用於查詢分布在乙個或多個不同資料來源中的大資料集。千萬不要以為presto可以解析sql,那麼presto就是乙個標準的資料庫。presto被設計為資料倉儲和資料分析產品 資料分析 大規模資料聚集和生...

整理遇到的不常見功能SQL,使用的SQL函式

自己整理了一下平時遇到的一些 sql 函式 sql server stuff character expression start length replacewith expression 函式功能 mysql 中可以用concat substr field,1,length field 3 fi...

工作上遇到DB2 SQL函式

1,將varchar型別的資料轉換成integer並選擇最大值,即 把字段型別的資料排序 select max cast sum max no as integer from dw product user yymm 2 用row number over partition by user id o...