本文首發(fā)于 vivo互聯(lián)網(wǎng)技術(shù) 微信公眾號
創(chuàng)新互聯(lián)是一家專注于做網(wǎng)站、成都網(wǎng)站設計與策劃設計,社旗網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設十余年,網(wǎng)設計領(lǐng)域的專業(yè)建站公司;建站業(yè)務涵蓋:社旗等地區(qū)。社旗做網(wǎng)站價格咨詢:18980820575
作者:李勇
目錄:
1.左表 join 后條件下推
2.左表join中條件不下推
3.右表join中條件下推
4.右表join中條件不下推
5.總結(jié)
在《SparkSql連接查詢中的謂詞下推處理(一)》中,我們介紹了一些基本的概念,并對內(nèi)連接查詢時的一些基本下推規(guī)則進行了分析。
本篇文章要介紹的是--外連接查詢中的謂詞下推規(guī)則,這相比內(nèi)連接中的規(guī)則要復雜一些,不過使用簡單的表格來進行分析也是可以分析清楚的。先上表:
我們以左外連接查詢?yōu)槔?,先總結(jié)規(guī)矩如下:
接下來對這個表格中的規(guī)則進行詳細的分析。
查詢語句如下:
前文有提到,對于join后條件,如果放在jo**in**操作后執(zhí)行,是可以作為正確結(jié)果進行比對的。那么先對兩表進行左連接,結(jié)果如下:
然后使用LT.id>1這個join后條件進行過濾,結(jié)果如下:
來分析一下LT.id>1下推到左表進行數(shù)據(jù)過濾的結(jié)果,經(jīng)過LT.id>1過濾后,左表變?yōu)椋?/p>
此時再和右表進行左連接,左表id為2的行,在右表中能找到id為2的行,則連接結(jié)果如下:
可見,兩種處理方法結(jié)果一致。條件下推過濾了左表整整50%的數(shù)據(jù)(相當牛,雖然只過濾了一條)。究其原因,是因為在SparkSQL中,把以上的查詢解析成了如下的子查詢:
這是一個非相關(guān)子查詢,即完全可以先完成子查詢,再完成父查詢,子查詢在查詢過程中和外部查詢沒有關(guān)聯(lián)關(guān)系。
查詢語句如下:
來看看不下推的情況下計算出的正確結(jié)果,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都保留。最終的查詢結(jié)果如下:
那么如果把"LT.id>1"這個條件下推到做表,會得到什么結(jié)果呢?
首先左表經(jīng)過"LT.id>1"過濾后,如下:
此時再和右表連接,左表id為2的行在右表中能找到,且滿足"LT.id = RT.id AND LT.id > 1"這個join中條件,所以兩表的value都被保留。左表中已經(jīng)沒有數(shù)據(jù)了,查詢結(jié)束,查詢結(jié)果如下:
這個查詢結(jié)果和不下推的正確結(jié)果不一致,是個錯誤的結(jié)果,所以左表join中條件是不能下推進行數(shù)據(jù)過濾的。分析原因:主要是因為join中條件和join后條件對結(jié)果的處理方式不同,前者在不滿足join條件時會保留一部分結(jié)果,而后者在不滿足條件時任何東西都不保留。
查詢語句如下:
現(xiàn)在把RT.id>1這個右表join后條件下推,來過濾右表,過濾后如下:
然后左表再和右表進行左連接,流程如下:
第一步:左表id為1的行在右表中沒有,此時左表值保留,右表為null;
第二步:左表id位2的行在右表中有,并且RT.id大于1,兩個join條件都滿足,則左表和右表的值都保留。查詢結(jié)果如下:
那么如果不下推(為了得到正確結(jié)果),來看看結(jié)果,流程如下:
第一步:左表id為1的行在右表中有,但是不滿足第二個join條件,所以這行算是沒join上,所以左表數(shù)據(jù)保留,右表為null;
第二步:左表id為2的行在右表中有,也滿足第二個join條件,所以左右表的數(shù)據(jù)都保留。
可見,右表join中條件下推不下推,結(jié)果一樣,所以,干嗎不下推?可以過濾掉一半的數(shù)據(jù)呢。SparkSQL中的等價處理語句是:
可以看出,也是解析成了一個非相關(guān)子查詢來處理的。
這個應該是最違反常規(guī)理解的查詢了,查詢語句如下:
首先來看,join后條件不下推的情況,流程如下:
第一步:左表id為1的行在右表中可以找到,但是此時僅僅滿足join條件,在使用where條件判斷這條連接后數(shù)據(jù)時,發(fā)現(xiàn)右表的id不滿足RT.id>1的條件,所以這條join結(jié)果不保留(注意:這里是不保留,全都不保留,左表右表都不保留,要跟上邊的沒join上而右表的值保留為null的情況區(qū)別開,這也是關(guān)鍵所在);
第二步:左表id為2的行和右表id為2的行join上了,同時也滿足RT.id>1的where條件。
這是一條符合語義的正確的查詢結(jié)果。
好了,接下來看看右表join后條件下推的情況:
第一步:使用RT.id>1過濾右表,過濾后右表只剩一行id為2的行;
第二步:左表id為1的行在過濾后的右表中沒有,此時左表值保留,右表值為null;
第三步:左表id為2的行在右表中有,此時左表值保留,右表值也保留。
結(jié)果如下:
很明顯這其實是一個錯誤的結(jié)果。
至此,左連接查詢的四條規(guī)則分析完了??梢钥闯?,在SparkSQL中對于外連接查詢時的過濾條件,并不能在所有情況下都用來進行數(shù)據(jù)源的過濾,如果使用得當會極大的提升查詢性能,如果使用不當,則會產(chǎn)生錯誤的查詢結(jié)果,而這種錯誤結(jié)果又不易發(fā)覺,所以使用時要格外小心。
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。