文章最前: 我是Octopus,這個名字來源于我的中文名--章魚;我熱愛編程、熱愛算法、熱愛開源。所有源碼在我的個人github?;這博客是記錄我學(xué)習(xí)的點點滴滴,如果您對 Python、Java、AI、算法有興趣,可以關(guān)注我的動態(tài),一起學(xué)習(xí),共同進步。
?相關(guān)文章:
-
LEFT ANTI JOIN的使用
-
Spark SQL優(yōu)化:NOT IN子查詢優(yōu)化解決
-
hivesql-dayofweek 函數(shù)
-
percentile_approx 聚合函數(shù)
背景
有如下的數(shù)據(jù)查詢場景。
SELECT a
,b
,c
,d
,e
,f
FROM xxx.BBBB
WHERE dt = '${zdt.addDay(0).format('yyyy-MM-dd')}'
AND predict_type
not IN
(
SELECT
distinct a
FROM
xxx.AAAAA
WHERE dt = '${zdt.addDay(0).format('yyyy-MM-dd')}'
)
分析
通過查看SQL語句的執(zhí)行計劃基本就可以判斷性能瓶頸所在。
| == Physical Plan ==
BroadcastNestedLoopJoin BuildRight,
Spark?SQL的優(yōu)化器最終將SQL優(yōu)化為了一個BroadcastNestedLoopJoin。
實際上就是在對JOIN兩側(cè)的數(shù)據(jù)做笛卡爾積運算。時間復(fù)雜度為O(),過濾前的結(jié)果集行數(shù)達到了萬億級別。
優(yōu)化方法
嘗試將NOT IN子查詢改寫成了LEFT JOIN形式
SELECT a.*
FROM
(
SELECT a
,b
,c
,d
,e
,f
FROM xxx.BBBB
WHERE dt = '${zdt.addDay(0).format('yyyy-MM-dd')}'
) a
LEFT JOIN
(
SELECT c
FROM xxx.AAAA
WHERE dt = '${zdt.addDay(0).format('yyyy-MM-dd')}'
) b
ON a.c = b.c
WHERE b.c is null
執(zhí)行計劃如下:
Filter is null(#391L)
+- SortMergeJoin
可以看到,JOIN方式變成了SortMergeJoin。
SortMergeJoin的原理是對JOIN兩側(cè)的數(shù)據(jù)排序后在做歸并。
不妨假設(shè):
排序的時間復(fù)雜度為O(nlogn)。
則SortMergeJoin整體的時間復(fù)雜度為O(n + nlogn),依然是百萬級數(shù)據(jù)量的過濾計算。
在數(shù)據(jù)庫查詢優(yōu)化中,"Broadcast Nested Loop Join" 和 "Sort Merge Join" 是兩種不同的關(guān)聯(lián)操作算法。
Broadcast Nested Loop Join:
在這種連接算法中,一張表被廣播到其他所有的節(jié)點上,然后與每個節(jié)點上的本地數(shù)據(jù)進行嵌套循環(huán)連接。這通常適用于一個小表和一個大表的連接,其中小表的數(shù)據(jù)可以很容易地廣播到所有節(jié)點上。
優(yōu)勢:
1. 適用于小表連接:?當一個表很小而另一個表很大時,廣播小表可以減少網(wǎng)絡(luò)傳輸和數(shù)據(jù)傳輸開銷。
2. 簡單性:?實現(xiàn)相對簡單,不需要進行大規(guī)模數(shù)據(jù)排序。
3. 內(nèi)存友好:?不需要大量的內(nèi)存,因為每次只處理小表的一行。
Sort Merge Join:
這是一種更加通用的連接算法,它不涉及表的廣播,而是將連接的列進行排序,然后按照排序結(jié)果進行逐對比較,從而執(zhí)行連接操作。
優(yōu)勢:
1. 適用于大表連接:當兩個表的大小都比較大時,Sort Merge Join 可以更好地處理連接操作,因為不需要將整個表廣播到各個節(jié)點。
2. 高效的順序訪問:由于涉及數(shù)據(jù)的排序,Sort Merge Join 可以更好地利用磁盤預(yù)讀,提高磁盤數(shù)據(jù)訪問效率。
3. 穩(wěn)定性:對于不同數(shù)據(jù)分布的情況,Sort Merge Join 的性能通常比 Broadcast Nested Loop Join 更穩(wěn)定。文章來源:http://www.zghlxwxcb.cn/news/detail-754801.html
所以,Broadcast Nested Loop Join 適用于小表和大表之間的連接,而 Sort Merge Join 則更適合連接兩個較大的表。但請注意,具體的性能取決于數(shù)據(jù)分布、硬件配置和數(shù)據(jù)庫管理系統(tǒng)的優(yōu)化能力。在實際情況中,優(yōu)化器可能會根據(jù)統(tǒng)計信息和其他因素來選擇最適合的連接算法。文章來源地址http://www.zghlxwxcb.cn/news/detail-754801.html
到了這里,關(guān)于Spark SQL優(yōu)化:NOT IN子查詢優(yōu)化解決的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!