<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Presto 原理 | Presto 中支持的七種 Join 類型

          共 4115字,需瀏覽 9分鐘

           ·

          2021-11-14 08:21

          Join 操作是最重要和最昂貴的 SQL 操作之一,需要數(shù)據(jù)庫工程師深入理解才能編寫高效的 SQL 查詢。從數(shù)據(jù)庫工程師的角度來看,了解 JOIN 操作的工作原理有助于他們優(yōu)化 JOIN 以實現(xiàn)高效執(zhí)行。我們在《Apache Spark 中支持的七種 Join 類型簡介》這邊文章中介紹了 Spark 相關(guān)的 JOIN 支持;這邊文章我們再來看下開源分布式計算引擎 Presto SQL 支持的 join 操作。

          幾乎所有眾所周知的數(shù)據(jù)庫都支持以下五種類型的 JOIN 操作:Cross Join, Inner Join, Left Join, Right Join 以及 Full Join。另外,Presto 內(nèi)部還有兩種類型的 JOIN 操作:Semi Join 和 Anti Join。本文從使用者的角度介紹了這七種類型的 JOIN。

          Cross Join

          Cross Join 返回兩張表的笛卡爾積,其 JOIN 過程不帶任何條件。換句話說,左表中的每一行都將與右表中的每一行連接起來。Cross Join 比其他類型的聯(lián)接更昂貴,因為它在兩個表之間進(jìn)行笛卡爾積。下面就是一個 Cross Join 的例子:

          presto:iteblog> SELECT * FROM (VALUES 1, 2) t("left"), (VALUES 3, 4) u("right"); left | right ------+-------    1 |     3     2 |     3     1 |     4     2 |     4 (4 rows)

          Inner Join

          Inner join 在一定條件下連接兩張表。只有在滿足給定條件時,表中的每一行才會與另一個表中的每一行連接。在 Presto SQL 中,INNER JOIN、JOIN 和帶有 WHERE 子句的分隔表都被視為 Inner join。如果查詢包含帶有 where 子句的逗號分隔表,如下所示,它將被讀取為 Cross Join,并在連接操作后應(yīng)用過濾器,后面會由 Presto 優(yōu)化器重寫為 Inner join 查詢。

          presto:iteblog> SELECT * FROM (VALUES 1, 2) t("left"), (VALUES 1, 1, 2) u("right")              WHERE t."left" = u."right"; left | right ------+-------    1 |     1     1 |     1     2 |     2 (3 rows)

          Left Outer Join

          與 Inner join 一樣,Left Outer Join 將左表中的每一行與右表中的匹配行連接起來。如果左表中的行在右表中沒有找到,那么右表中對應(yīng)的列用空值來填充。在 Presto SQL 中,關(guān)鍵字 OUTER 在 LEFT OUTER JOIN 操作中是可選的。換句話說,LEFT JOIN 和 LEFT OUTER JOIN 的意思是一樣的。

          presto:iteblog> SELECT * FROM (VALUES 1, 2) t("left")              LEFT OUTER JOIN (VALUES 1, 1) u("right")              ON t."left" = u."right"; left | right------+-------    1 |     1    1 |     1    2 | NULL(3 rows)

          Right Outer Join

          Right Outer Join 將右表中的每一行與左表中的匹配行連接起來。如果右表中的行在左表中沒有找到,那么左表中對應(yīng)的列用空值來填充。在 Presto SQL 中,關(guān)鍵字 OUTER 在 RIGHT OUTER JOIN 操作中是可選的。換句話說,RIGHT JOIN 和 RIGHT OUTER JOIN 的意思是一樣的。

          presto:iteblog> SELECT * FROM (VALUES 1, 2) t("left")              RIGHT OUTER JOIN (VALUES 1, 2, 3) u("right")              ON t."left" = u."right"; left | right ------+-------    1 |     1     2 |     2  NULL |     3 (3 rows)

          Full Outer Join

          Full Outer Join 可以看作是左外連接和右外連接的組合。它將每一側(cè)的每一行與另一側(cè)的匹配行連接起來。如果左表中的行在右表中沒有找到,那么右表中對應(yīng)的列用空值來填充。同樣,如果右表中的行在左表中沒有找到,那么左表中對應(yīng)的列用空值來填充。在 Presto SQL 中,關(guān)鍵字 OUTER 在 FULL OUTER JOIN 操作中是可選的。換句話說,F(xiàn)ULL JOIN 和 FULL OUTER JOIN 的意思是一樣的。

          presto:iteblog> SELECT * FROM (VALUES 1, 2) t("left")              FULL OUTER JOIN (VALUES 1, 3) u("right")              ON t."left" = u."right"; left | right------+-------    1 |     1    2 | NULL NULL |     3(3 rows)

          除了上面提到的 JOIN 類型之外,還有兩種 JOIN 類型:Semi Join 以及 Anti Join。這兩個 JOIN 一般是 Presto 改寫用戶 SQL 產(chǎn)生的。

          Semi Join

          在 Presto 內(nèi)部,IN/EXISTS 中帶子查詢就會被翻譯成 Semi Join,Semi Join 有兩種變體:Left Semi Join 和 Right Semi Join。顧名思義,Left Semi Join 計算條件,如果左表中有匹配的行,則返回左表中的行。類似地,Right Semi Join 只返回右邊表中匹配的行。以下使用 IN 謂詞的查詢被 Presto 優(yōu)化器轉(zhuǎn)換成 Semi Join:

          presto:iteblog> SELECT o_orderkey,o_custkey FROM orders              WHERE o_orderkey IN (SELECT o_orderkey                           FROM orders                           WHERE o_orderstatus = 'o' AND o_orderdate = '1996-01-02'); o_orderkey | o_custkey------------+-----------     454791 |         1   48313376 |         1   22402209 |         1   49312295 |         1   29469061 |         1   58877861 |         1   27843492 |         1    7855620 |         1   17904289 |         1   23747713 |         1(10 rows)

          Anti Join

          Anti Join 是 Presto 另一種內(nèi)部使用的 JOIN,用于在聯(lián)接條件不匹配時從表中返回行。它與 Semi Join 類似,只返回一個表中的行,但 Join 條件與 Semi Join 相反。例如,可以使用 Anti Join 評估以下 NOT IN 查詢。

          presto:iteblog> SELECT o_orderkey,o_custkey FROM orders              WHERE o_orderkey IN (SELECT o_orderkey                           FROM orders                           WHERE o_orderstatus = 'o' AND o_orderdate = '1996-01-02'); o_orderkey | o_custkey------------+-----------   58781825 |   1002496   11692451 |    479269   45393222 |    145972   53041377 |    371935   19746180 |    730093     485186 |    653602   46238592 |     47099   43451713 |    152060   43661861 |     62653(9 rows)

          盡管 Anti Join 可以被視為一種不同的 JOIN 類型,但在 Presto 內(nèi)部通過否定連接條件將其視為 Semi Join。不僅是 Semi Join,任何 JOIN 操作都可以使用其他 JOIN 組成。例如,通過交互參與 JOIN 的表的位置 ,可以將 left outer join 重寫為 right outer join。

          瀏覽 95
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色污污视频网站在线观看 | 美女裸体网站国产 | A片黄色电影一级片 | 思思热视频在线 | 日韩无码黄片 |