談一談spark SQL的調優經驗

2021-10-24 05:39:22 字數 2861 閱讀 6215

sql是一種結構化的資料庫查詢語言。而spark sql是spark套件中的乙個元件,它將資料的計算任務通過sql的形式轉換成了rdd的計算,類似於hive通過sql的形式將資料的計算任務轉換成了mapreduce。

通常來說hadoop是一整套大資料解決方案,包括了儲存(hdfs)、計算(mapreduce)和資源排程管理(yarn)。hive是hadoop生態發展起來的乙個資料倉儲,可以使用hive sql實現mr,並且將hdfs對映成表。而spark是基於記憶體計算的大資料平行計算框架,可以更快第實現資料計算。

大部分的sql,解析執行過程類似:通常使用者在客戶端傳送sql請求,先判斷請求是否合法,包括許可權檢查等;然後sql解析器對sql進行語法語義的解析,sql優化器會生成最優執行計畫。

要對sql調優,肯定是要對sql關鍵字執行順序有所認識。這樣便於我們更好地調整sql。以下是一條sql所有關鍵字執行順序。

sql的所有操作,可以分為簡單操作(如過濾where、限制次數limit等)和聚合操作(group by,join等),join操作是最複雜、代價最大的操作型別。

當前sparksql支援三種join演算法–shuffle hash join、broadcast hash join以及sort merge broadcast。其中前兩者歸根到底都屬於hash join,只不過在hash join之前需要先shuffle還是先broadcast。詳細可參考:

我們在實際應用中要盡可能避免大表和大表的join。

spark sql的優化可以遵循以下幾個原則:

明確需求

探索資料

良好**習慣

裁剪資料

關注連線條件

善用分析函式

轉變思維

了解sql執行原理

第8條在第一部分做了一定的**,接下來主要討論前面7條。

在寫sql或對sql優化前,一定要明確需求,了解其意圖。這樣可以少走非常的多的彎路。如果在沒有十分清楚需求前,如果是寫sql,二話不說就是幹,最後雖然寫出來,但是過於複雜,原本非常簡單可以實現。如果需要優化別人的sql,也需要了解需要優化的需求到底是想幹什麼。

探索資料是乙個非常好的習慣,有助於你對所統計的資料來源有乙個直接的認識。如拿到乙個表,最先要了解基本資料字典,然後select一下,看看各個字段到底是什麼。需要統計的連線條件是唯一,有沒有空值,資料量級多大。另外表與表的對應關係,資料流統計表的記錄情況,都是我們需要了解的。這些都會對我們優化sql有比較好的指導意義。

任何**,都需要保持乙個良好的編碼習慣,sql也一樣。這樣可以使sql更易讀、易維護。同樣也使得sql變得整潔、優美。下面是一段規範的sql**:

裁剪資料目的是為了減少資料量。包含列裁剪和行過濾。

列裁剪是指select部分盡可能只把需要的列寫出來,不要什麼都寫*,這樣spark需要掃瞄讀取更多的資料。

行過濾是指where部分,需要盡量縮小查詢範圍。

前面我們已知道join是代價最大的一種操作。如果涉及到多表join,一定是需要先過濾再join。不要吧過濾條件寫到on上。

ql優化最難處理的就是join操作了,談到join自然就要聊到on,也就是連線條件。很多新同學經常遇到的問題就是忘了寫連線條件,連線條件寫的不對,常常造成笛卡爾積、資料傾斜(後面會詳細討論)。這樣跑了好久還不出來,關鍵如果sql很長,還不好看出來。

對於連線條件,我們應該做到以下幾點:

1)兩個子表的連線條件,盡量要保證連線鍵在兩個子表中是唯一的。

2)連線鍵僅寫等值連線,不要出現不等值連線,如:<>,like等。所有的不等值連線,都需要轉換成等值連線。

3)盡量不要傳遞連線,所有子表都應該與主表連線。

spark sql給我們提供了豐富的分析函式,這些函式可以讓我們sql做更多的事,而且是**更加優雅,提高查詢效率。

常用的分析函式:

rank:值排名相同,其排名跳躍不連續

row_number:值排名,其排名連續不跳躍

dense_rank:值排名相同,其排名不連續不跳躍

小練習

有一場籃球賽,參賽雙方是a隊和b隊,場邊記錄員記錄下了每次得分的詳細資訊:

team:隊名,number:球衣號,name:球員姓名,score_time:得分時間,score:當次得分

問(用sql表達):

1)輸出每一次的比分的反超時刻,以及對應的完成反超的球員姓名

2)輸出連續三次或以上得分的球員姓名,以及那一撥連續得分的數值

比如遇到sql也寫的最優了,似乎沒什麼可以優化了。但是sql就是跑不出。我的需求就是需要這麼大的時間範圍,幾個月甚至幾年;就是需要這麼多的資料量幾億,幾十億。還要多表連線,怎麼辦?

這個時候需要我們轉變思維。乙個是業務的思維,乙個是預計算+分層思想

業務思維:

1)你真的理解清楚了需求嗎?

2)一定需要這麼久的時間範圍?

3)一定需要這麼多的資料量嗎?

4)一定需要一次性計算嗎?

預計算+分層思想:

1)增量+存量合併

2)分層預先計算資料中間表,逐層減少資料粒度與資料量級

一些常用的Spark SQL調優技巧

一些常用的spark sql調優技巧 使用快取表 在sparksql中,當我們建立表時,我們可以通過呼叫spark.catalog.cachetable tablename 或者dataframe.cache 的方式將表快取起來。這樣spark sql將僅掃瞄所需的列,並自動調整壓縮以最小化記憶體使...

談一談C 的事件

c 中事件基於委託,要理解事件要先理解委託,如果覺得自己關於委託不是很了解可以看看我前面寫委託的文章 使用委託時,一般會出現兩種角色 廣播者 發布者 和訂閱者,這是乙個非常常見的模型 using system class program 定義 發布 委託 public delegate void p...

談一談 define中 和 的作用

最近在閱讀大佬們寫的開源庫的時候,看到一些巨集定義,不是很明白它的用法,就查了很多資料,弄清楚它們的用法後,在這裡記錄一下。1 的作用 param指把param當成符號,就是把 後面的看成字串 define test1 param param include intmain int argc,cha...