1. 問題背景:
在工作中中遇到個問題,那就是乙個 大表a left join 乙個很小的表 b
查詢速度總是很慢, 就想著怎麼去優化,於是就查了些資料,得到可以通過
設定 broadcastjoin的方式來優化,但是呢,這種方法很多都是使用scala
的語法去寫dataframe的方式實現,但是這太大費周章了,於是找到了hint的方法
2. spark關聯方式的知識(broadcast join、shuffle hash join和sort merge join)
1. 小表對大表(broadcast join)
將小表的資料分發到每個節點上,供大表使用。executor儲存小表的全部資料,一定程度上犧牲了空間,換取shuffle操作大量的耗時,這在sparksql中稱作broadcast join
broadcast join的條件有以下幾個:
*被廣播的表需要小於 spark.sql.autobroadcastjointhreshold 所配置的值,預設是10m (或者加了broadcast join的hint)
*基表不能被廣播,比如 left outer join 時,只能廣播右表
2. shuffle hash join
分為兩步:
對兩張表分別按照join keys進行重分割槽,即shuffle,目的是為了讓有相同join keys值的記錄分到對應的分割槽中
對對應分割槽中的資料進行join,此處先將小表分割槽構造為一張hash表,然後根據大表分割槽中記錄的join keys值拿出來進行匹配
3. 大表對大表(sort merge join)
將兩張表按照join keys進行了重新shuffle,保證join keys值相同的記錄會被分在相應的分割槽。分割槽後對每個分區內的資料進行排序,排序後再對相應的分區內的記錄進行連線
因為兩個序列都是有序的,從頭遍歷,碰到key相同的就輸出;如果不同,左邊小就繼續取左邊,反之取右邊
3. explain的基礎知識
explain + select 語句
執行即可檢視 這個段查詢的 執行計畫,即 查詢會按照什麼樣的方式執行
4. 解決問題:
1. 首先要確定這個大表a left join 小表b 現在使用的什麼樣的關聯方式
執行explain select * from a join b on a.id = b.id
然後 檢視執行計畫,檢視關鍵字是否有broadcast,如果有,那就不需要
指定broadcast這種關聯方式,再找其他優化方式,如果沒有
2. 那就 增加hint 指定broadcast的關聯方式,具體方式為
select + /*+ broadcastjoin(b) */
這裡需要注意的點是 b如果是子查詢的話,那麼b就是這個子查詢的別名
3. 然後就是查詢驗證,完成了優化
小表驅動大表
類似迴圈巢狀。for int i 5 如果小的迴圈在外層,對於資料庫連線來說就只連線5次,進行5000次操作,如果1000在外,則需要進行1000次資料庫連線,從而浪費資源,增加消耗。這就是為什麼要小表驅動大表。在tb dept bigdata表中插入100條資料,在tb emp bigdata表中...
OLAP 大表和小表並行hash join
乙個表50mb 乙個表10gb 50m表做驅動表,放在pga裡 這時候慢在對對 10g 的全表掃瞄 對10個g掃瞄塊 需要開並行 我有這樣乙個演算法 乙個程序 讀 50mb 8程序 來 掃瞄 10gb 乙個 程序掃瞄 1.25gb 50mb 都分發到 8個程序 超大表和小表之間做hash join,...
MySQL 小表驅動大表
小表驅動大表 準備兩站表 create table student id int 11 notnull,no varchar 20 default null name varchar 20 default null primary key id engine innodb default chars...