hive只支持等鏈接,外鏈接,左半鏈接。hive不支持非相等的join條件(經過其餘方式實現,如left outer join),由於它很難在map/reduce中實現這樣的條件。並且,hive能夠join兩個以上的表。html
只有等鏈接才容許jquery
hive> SELECT a.* FROM a JOIN b ON (a.id = b.id); hive> SELECT a.* FROM a JOIN b ON (a.id = b.id AND a.department = b.department);
同個查詢,能夠join兩個以上的表apache
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2);
hive轉換多表join時,若是每一個表在join字句中,使用的都是同一個列,只會轉換爲一個單獨的map/reduce。緩存
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1);
被轉換爲兩個map/reduce任務,由於b的key1列在第一個join條件使用,而b表的key2列在第二個join條件使用。第一個map/reduce任務join a和b。第二個任務是第一個任務的結果join c。app
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2);
在join的每一個map/reduce階段,序列中的最後一個表,當其餘被緩存時,它會流到reducers。因此,reducers須要緩存join關鍵字的特定值組成的行,經過組織最大的表出如今序列的最後,有助於減小reducers的內存。oop
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1);
三個表,在同一個獨立的map/reduce任務作join。a和b的key對應的特定值組成的行,會緩存在reducers的內存。而後reducers接受c的每一行,和緩存的每一行作join計算。學習
hive> SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2);
這裏有兩個map/reduce任務在join計算被調用。第一個是a和b作join,而後reducers緩存a的值,另外一邊,從流接收b的值。第二個階段,reducers緩存第一個join的結果,另外一邊從流接收c的值。spa
在join的每一個map/reduce階段,經過關鍵字,能夠指定哪一個表從流接收。code
hive> SELECT /*+ STREAMTABLE(a) */ a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1);
三個表的鏈接,會轉換爲一個map/reduce任務,reducer會把b和c的key的特定值緩存在內存裏,而後從流接收a的每一行,和緩存的行作join。orm
LEFT,RIGHT,FULL OUTER鏈接存在是爲了提供ON語句在沒有匹配時的更多控制。例如,這個查詢:
hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key);
將會返回a的每一行。若是b.key等於a.key,輸出將是a.val,b.val,若是a沒有和b.key匹配,輸出的行將是 a.val,NULL。若是b的行沒有和a.key匹配上,將被拋棄。語法"FROM a LEFT OUTER JOIN b"必須寫在一行,爲了理解它如何工做——這個查詢,a是b的左邊,a的全部行會被保持;RIGHT OUTER JOIN將保持b的全部行, FULL OUTER JOIN將會保存a和b的全部行。OUTER JOIN語義應該符合標準的SQL規範。
Joins發生在where字句前,因此,若是要限制join的輸出,須要寫在where字句,不然寫在JOIN字句。如今討論的一個混亂的大點,就是分區表
hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key) WHERE a.ds='2018-05-22' AND b.ds='2018-05-22';
將會鏈接a和b,產生a.val和b.val的列表。WHERE字句,也能夠引用join的輸出列,而後過濾他們。 可是,不管什麼時候JOIN的行找到a的key,可是找不到b的key時,b的全部列會置成NULL,包括ds列。這就是說,將過濾join輸出的全部行,包括沒有合法的b.key的行。而後你會在LEFT OUTER的要求撲空。 也就是說,若是你在WHERE字句引用b的任何列,LEFT OUTER的部分join結果是不相關的。因此,當外鏈接時,使用這個語句
hive> SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key AND b.ds='2018-05-22' AND a.ds='2018-05-22';
join的輸出會預先過濾,而後你不用對有a.key而沒有b.key的行作過濾。RIGHT和FULL join也是同樣的邏輯。
join是不可替換的,鏈接是從左到右,不論是LEFT或RIGHT join。
hive> SELECT a.val1, a.val2, b.val, c.val FROM a JOIN b ON (a.key = b.key) LEFT OUTER JOIN c ON (a.key = c.key);
首先,鏈接a和b,扔掉a和b中沒有匹配的key的行。結果表再鏈接c。這提供了直觀的結果,若是有一個鍵都存在於A和C,但不是B:完整行(包括 a.val1,a.val2,a.key)會在"a jOIN b"步驟,被丟棄,由於它不在b中。結果沒有a.key,因此當它和c作LEFT OUTER JOIN,c.val也沒法作到,由於沒有c.key匹配a.key(由於a的行都被移除了)。相似的,RIGHT OUTER JOIN(替換爲LEFT),咱們最終會更怪的效果,NULL, NULL, NULL, c.val。由於儘管指定了join key是a.key=c.key,咱們已經在第一個JOIN丟棄了不匹配的a的全部行。
爲了達到更直觀的效果,相反,咱們應該從
hive> FROM c LEFT OUTER JOIN a ON (c.key = a.key) LEFT OUTER JOIN b ON (c.key = b.key);
LEFT SEMI JOIN實現了相關的IN / EXISTS的子查詢語義的有效途徑。因爲Hive目前不支持IN / EXISTS的子查詢,因此你能夠用 LEFT SEMI JOIN 重寫你的子查詢語句。LEFT SEMI JOIN 的限制是, JOIN 子句中右邊的表只能在 ON 子句中設置過濾條件,在 WHERE 子句、SELECT 子句或其餘地方過濾都不行。
hive> SELECT a.key, a.value FROM a WHERE a.key in (SELECT b.key FROM B);
能夠重寫爲
hive> SELECT a.key, a.val FROM a LEFT SEMI JOIN b on (a.key = b.key);
但若是全部被鏈接的表是小表,join能夠被轉換爲只有一個map任務。查詢是
hive> SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key;
不須要reducer。對於每個mapper,A和B已經被徹底讀出。限制是a FULL/RIGHT OUTER JOIN b不能使用。
若是表在join的列已經分桶了,其中一張表的桶的數量,是另外一個表的桶的數量的整倍,那麼二者能夠作桶的鏈接。若是A有4個桶,表B有4個桶,下面的鏈接:
hive> SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key;
只能在mapper工做。爲了爲A的每一個mapper完整抽取B。對於上面的查詢,mapper處理A的桶1,只會抽取B的桶1,這不是默認行爲,要使用如下參數:
hive> set hive.optimize.bucketmapjoin = true;
若是表在join的列通過排序,分桶,並且他們有相同數量的桶,可使用排序-合併 join。每一個mapper,相關的桶會作鏈接。若是A和B有4個桶
hive> SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM A a join B b on a.key = b.key;
只能在mapper使用。使用A的桶的mapper,也會遍歷B相關的桶。這個不是默認行爲,須要配置如下參數:
hive> set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat; hive> set hive.optimize.bucketmapjoin = true; hive> set hive.optimize.bucketmapjoin.sortedmerge = true;
以上就是博主爲你們介紹的這一板塊的主要內容,這都是博主本身的學習過程,但願能給你們帶來必定的指導做用,有用的還望你們點個支持,若是對你沒用也望包涵,有錯誤煩請指出。若有期待可關注博主以第一時間獲取更新哦,謝謝!