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...