簡體   English   中英

謂詞下推 vs On 子句

[英]Predicate Pushdown vs On Clause

在 Hive 中執行連接然后使用 where 子句過濾輸出時,Hive 編譯器將嘗試在連接表之前過濾數據。 這稱為謂詞下推( http://allabouthadoop.net/what-is-predicate-pushdown-in-hive/

例如:

SELECT * FROM a JOIN b ON a.some_id=b.some_other_id WHERE a.some_name=6

如果啟用了下推謂詞(hive.optimize.ppd),則表 a 中 some_name = 6 的行將在執行連接之前被過濾。

但是,我最近還了解到,在將表與另一個表連接之前,還有另一種過濾數據的方法( https://vinaynotes.wordpress.com/2015/10/01/hive-tips-joins-occur-before -where-子句/ )。

可以在ON子句中提供條件,表a將在執行聯接之前進行過濾

例如:

SELECT * FROM a JOIN b  ON a.some_id=b.some_other_id AND a.some_name=6

這兩者都提供謂詞下推優化嗎?

謝謝

兩者都是有效的,在 INNER JOIN 和 PPD 的情況下,兩者的工作方式相同。 但是這些方法在 OUTER JOINS 的情況下工作方式不同

ON 加入條件在加入之前起作用。

加入后應用WHERE。

優化器決定謂詞下推是否適用,它可能會起作用,但在 LEFT JOIN 的情況下,例如右表上的 WHERE 過濾器WHERE 過濾器

SELECT * FROM a 
             LEFT JOIN b ON a.some_id=b.some_other_id 
 WHERE b.some_name=6 --Right table filter

將限制 NULL, LEFT JOIN將被轉換為INNER JOIN ,因為如果 b.some_name=6,它不能為 NULL。

而 PPD 不會改變這種行為。

如果在右表中添加允許 NULL 的額外 OR 條件,您仍然可以使用 WHERE 過濾器執行 LEFT JOIN:

SELECT * FROM a 
             LEFT JOIN b ON a.some_id=b.some_other_id 
 WHERE b.some_name=6 OR b.some_other_id IS NULL --allow not joined records

如果您有多個連接和許多這樣的過濾條件,這樣的邏輯會使您的查詢難以理解和錯誤修剪。

LEFT JOIN with ON filter 不需要額外的 OR 條件,因為它在 join 之前過濾了右表,這個查詢按預期工作並且易於理解:

SELECT * FROM a 
             LEFT JOIN b ON a.some_id=b.some_other_id and b.some_name=6

PPD 仍然適用於 ON 過濾器,如果表 b 是 ORC,PPD 會將謂詞推送到盡可能低的級別給 ORC 閱讀器,並將使用內置的 ORC 索引在三個級別進行過濾:行、條帶和文件。

更多關於同一主題和一些測試: https : //stackoverflow.com/a/46843832/2700344

因此,無論是否使用 PPD,最好使用帶有 ON 條件和 ON 過濾的顯式 ANSI 語法,以盡可能保持查詢簡單並避免無意中轉換為 INNER JOIN。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM