日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

sql语句换行_Spark随笔|关于Bucket Table与SQL语句转换

發(fā)布時(shí)間:2024/9/15 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sql语句换行_Spark随笔|关于Bucket Table与SQL语句转换 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Bucket Table

Bucket?Table是一種Spark常見(jiàn)的優(yōu)化查詢的建表方式。創(chuàng)建方式是使用distributed by語(yǔ)法進(jìn)行創(chuàng)建,會(huì)根據(jù)spark.sql.shuffle.partitions的值創(chuàng)建若干個(gè)bucket。Spark中對(duì)于兩個(gè)大表的join,采用的方式是SortMergeJoin.而如果兩個(gè)表都是bucket表,而且bucket數(shù)量相同(業(yè)界有公司針對(duì)這塊的優(yōu)化,如果兩個(gè)bucket表bucket數(shù)量是倍數(shù)關(guān)系也可以進(jìn)行bucket join),那么可以跳過(guò)sort和shuffle,直接進(jìn)行join, 會(huì)產(chǎn)生較好的性能,通常需要業(yè)務(wù)方會(huì)約定好bucket的數(shù)量。

Spark針對(duì)bucket表讀取的時(shí)候,會(huì)對(duì)每一個(gè)bucket分配一個(gè)task來(lái)讀取,因?yàn)槿绻M(jìn)行bucket join就不能再對(duì)這個(gè)bucket的數(shù)據(jù)進(jìn)行拆分。但是問(wèn)題來(lái)了,我們并不是每次讀取bucket表都是為了進(jìn)行bucket join,比如說(shuō)有時(shí)候我們會(huì)對(duì)這個(gè)bucket進(jìn)行更新操作。如果只是單純的對(duì)這個(gè)bucket表進(jìn)行一些處理操作,例如就是一個(gè)單純的shuffle操作。而這個(gè)bucket表的每個(gè)bucket都特別大,例如大于1個(gè)G,而在shuffle write階段要生成3G的數(shù)據(jù)。那么這時(shí)候?qū)γ總€(gè)bucket分配一個(gè)task來(lái)處理就會(huì)非常吃力。

其實(shí)Spark?SQL中有一個(gè)參數(shù)spark.sql.sources.bucketing.enabled,默認(rèn)是true。如果我們將這個(gè)參數(shù)設(shè)置為false,那么spark就會(huì)將一個(gè)bucket table看做一個(gè)普通的table。這意味著什么呢?Spark對(duì)于普通表,如果他的單個(gè)文件大于一個(gè)hdfs ?block大小(通常是128M),而且這個(gè)文件又是可拆分的(例如text文本,snappy 壓縮格式的parquet文件等等),那么Spark會(huì)按照這個(gè)文件拆分,分配多個(gè)task來(lái)處理。因此,針對(duì)我們上面的場(chǎng)景,設(shè)置這個(gè)參數(shù)為false,可以大大的加快map階段的執(zhí)行,起到優(yōu)化的效果。

解析和更改Spark SQL語(yǔ)句

如果你有對(duì)一個(gè)Spark?SQL語(yǔ)句進(jìn)行解析和更改部分語(yǔ)句的需求。

例如我需求對(duì)一條SQL中的表名進(jìn)行映射修改,或者對(duì)其中的UDF(其實(shí)在Spark?SQL中function和table是很類似的東西)和location信息進(jìn)行修改。

可能首先想到的就是使用正則進(jìn)行字符串匹配,去尋找自己需要的字段,但是這種方法十分的不靠譜,因?yàn)镾QL的語(yǔ)法十分復(fù)雜,我們很難完全準(zhǔn)確的抓取到自己需要的信息。

所以我們能不能根據(jù)抽象語(yǔ)法樹(shù)去拿到我們想要的字段呢?答案當(dāng)然是OK的,一條SQL語(yǔ)句進(jìn)行解析器之后都成為一個(gè)抽象語(yǔ)法樹(shù),每個(gè)TreeNode都有自己的類型,我們可以根據(jù)這些類型拿到自己想要的信息,比如table name,function name,location等等信息(table根據(jù)TableIdentifier類型節(jié)點(diǎn)獲得,function根據(jù)FunctionIdentifier, location信息從LoadDataCommand或者CreateTableCommand中獲取)。如下圖所以,一條SQL語(yǔ)句INSERT INTO TRABLE tb SELECT ta.id FROM ta JOIN tb on ta.id=tb.id會(huì)被大概轉(zhuǎn)化為下面一個(gè)AST.

但是,當(dāng)我們拿到我們想要的信息,之后如何轉(zhuǎn)換想要的SQL呢?

我第一想法是說(shuō),直接修改這個(gè)AST,然后將這個(gè)AST轉(zhuǎn)化為一條SQL語(yǔ)句。但是AST轉(zhuǎn)SQL很麻煩的事情,需要你自己精通SQL語(yǔ)法,然后寫一套 Plan轉(zhuǎn)String的規(guī)則。這聽(tīng)起來(lái)就很麻煩。好在經(jīng)過(guò)一番探索:

  • Spark使用antlr v4進(jìn)行sql解析

  • 每個(gè)SQL最開(kāi)始解析為一個(gè)原始的AST(parsedPlan,未經(jīng)過(guò)analyze/optimize)

  • 這個(gè)SQL也對(duì)應(yīng)一個(gè)ParserRuleContext(package?org.antlr.v4.runtime)

ParserRuleContext其實(shí)也是一棵樹(shù),類似于AST,但是它的每個(gè)葉子節(jié)點(diǎn)會(huì)對(duì)應(yīng)一段text,也就是說(shuō)對(duì)應(yīng)一部分原始的SQL語(yǔ)句(table對(duì)應(yīng)TableIdentifierContext,function對(duì)應(yīng)QualifiedNameContext, location對(duì)應(yīng)LocationSpecContext)。

感興趣的話可以去看這個(gè)類的源碼:

https://github.com/antlr/antlr4/blob/master/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java。

前面我們提到的語(yǔ)句會(huì)被轉(zhuǎn)化為下面的一棵樹(shù),我這里是將其轉(zhuǎn)為String打印出來(lái),在每個(gè)節(jié)點(diǎn)處進(jìn)行換行。

有了這樣的兩棵樹(shù)AST和ParserRuleContext,我們就可以根據(jù)第一棵樹(shù),拿到我們想要的信息,然后再在第二棵樹(shù)上面找到其對(duì)應(yīng)的偏移量。然后對(duì)對(duì)應(yīng)部分進(jìn)行替換,之后再把第二棵樹(shù)的碎片對(duì)應(yīng)的文本拼接起來(lái)就好了。

HBase?官方社區(qū)推薦必讀好文

HBase 原理|HBase 內(nèi)存管理之 MemStore 進(jìn)化論

HBase 抗戰(zhàn)總結(jié)|阿里巴巴 HBase 高可用8年抗戰(zhàn)回憶錄

HBase 實(shí)踐|說(shuō)好不哭,但 HBase 2.0 真的好用到哭

↓掃碼關(guān)注?HBase?技術(shù)社區(qū)公眾號(hào)↓

總結(jié)

以上是生活随笔為你收集整理的sql语句换行_Spark随笔|关于Bucket Table与SQL语句转换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。