本文首發於 vivo互聯網技術 微信公衆號 https://mp.weixin.qq.com/s/II48YxGfoursKVvdAXYbVg
做者:李勇
目錄:
1.左表 join 後條件下推
2.左表join中條件不下推
3.右表join中條件下推
4.右表join中條件不下推
5.總結segmentfault
在《SparkSql鏈接查詢中的謂詞下推處理(一)》中,咱們介紹了一些基本的概念,並對內鏈接查詢時的一些基本下推規則進行了分析。微信
本篇文章要介紹的是--外鏈接查詢中的謂詞下推規則,這相比內鏈接中的規則要複雜一些,不過使用簡單的表格來進行分析也是能夠分析清楚的。先上表:性能
咱們以左外鏈接查詢爲例,先總結規矩以下:spa
接下來對這個表格中的規則進行詳細的分析。rem
查詢語句以下:get
前文有提到,對於join後條件,若是放在join操做後執行,是能夠做爲正確結果進行比對的。那麼先對兩表進行左鏈接,結果以下:it
而後使用LT.id>1這個join後條件進行過濾,結果以下:class
來分析一下LT.id>1下推到左表進行數據過濾的結果,通過LT.id>1過濾後,左表變爲:互聯網
此時再和右表進行左鏈接,左表id爲2的行,在右表中能找到id爲2的行,則鏈接結果以下:方法
可見,兩種處理方法結果一致。條件下推過濾了左表整整50%的數據(至關牛,雖然只過濾了一條)。究其緣由,是由於在SparkSQL中,把以上的查詢解析成了以下的子查詢:
這是一個非相關子查詢,即徹底能夠先完成子查詢,再完成父查詢,子查詢在查詢過程當中和外部查詢沒有關聯關係。
查詢語句以下:
來看看不下推的狀況下計算出的正確結果,join過程以下:
第一步:左表id爲1的行在右表中能找到相等的id,可是左表的id爲1,是不知足第二個join條件(LT.id>1)的,因此左表這一條至關於沒有和右表join上,因此左表的值value保留,而右表的value爲null(你沒知足join中條件沒join上還把你的值保留,給我搞個空值?沒辦法,就是這麼任性)。
第二步:左表id爲2的行在右表中能找到,並且左表id爲2的行的id大於1,兩個join條件都知足,因此算是和右表join上了,因此左表和右表的value都保留。最終的查詢結果以下:
那麼若是把"LT.id>1"這個條件下推到作表,會獲得什麼結果呢?
首先左表通過"LT.id>1"過濾後,以下:
此時再和右錶鏈接,左表id爲2的行在右表中能找到,且知足"LT.id = RT.id AND LT.id > 1"這個join中條件,因此兩表的value都被保留。左表中已經沒有數據了,查詢結束,查詢結果以下:
這個查詢結果和不下推的正確結果不一致,是個錯誤的結果,因此左表join中條件是不能下推動行數據過濾的。分析緣由:主要是由於join中條件和join後條件對結果的處理方式不一樣,前者在不知足join條件時會保留一部分結果,然後者在不知足條件時任何東西都不保留。
查詢語句以下:
如今把RT.id>1這個右表join後條件下推,來過濾右表,過濾後以下:
而後左表再和右表進行左鏈接,流程以下:
第一步:左表id爲1的行在右表中沒有,此時左表值保留,右表爲null;
第二步:左表id位2的行在右表中有,而且RT.id大於1,兩個join條件都知足,則左表和右表的值都保留。查詢結果以下:
那麼若是不下推(爲了獲得正確結果),來看看結果,流程以下:
第一步:左表id爲1的行在右表中有,可是不知足第二個join條件,因此這行算是沒join上,因此左表數據保留,右表爲null;
第二步:左表id爲2的行在右表中有,也知足第二個join條件,因此左右表的數據都保留。
可見,右表join中條件下推不下推,結果同樣,因此,幹嘛不下推?能夠過濾掉一半的數據呢。SparkSQL中的等價處理語句是:
能夠看出,也是解析成了一個非相關子查詢來處理的。
這個應該是最違反常規理解的查詢了,查詢語句以下:
首先來看,join後條件不下推的狀況,流程以下:
第一步:左表id爲1的行在右表中能夠找到,可是此時僅僅知足join條件,在使用where條件判斷這條鏈接後數據時,發現右表的id不知足RT.id>1的條件,因此這條join結果不保留(注意:這裏是不保留,全都不保留,左表右表都不保留,要跟上邊的沒join上而右表的值保留爲null的狀況區別開,這也是關鍵所在);
第二步:左表id爲2的行和右表id爲2的行join上了,同時也知足RT.id>1的where條件。
這是一條符合語義的正確的查詢結果。
好了,接下來看看右表join後條件下推的狀況:
第一步:使用RT.id>1過濾右表,過濾後右表只剩一行id爲2的行;
第二步:左表id爲1的行在過濾後的右表中沒有,此時左表值保留,右表值爲null;
第三步:左表id爲2的行在右表中有,此時左表值保留,右表值也保留。
結果以下:
很明顯這實際上是一個錯誤的結果。
至此,左鏈接查詢的四條規則分析完了。能夠看出,在SparkSQL中對於外鏈接查詢時的過濾條件,並不能在全部狀況下都用來進行數據源的過濾,若是使用得當會極大的提高查詢性能,若是使用不當,則會產生錯誤的查詢結果,而這種錯誤結果又不易發覺,因此使用時要格外當心。
更多內容敬請關注 vivo 互聯網技術 微信公衆號
注:轉載文章請先與微信號:labs2020 聯繫。