日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Left join優(yōu)化改寫為Right join

更新時(shí)間:

Left join是實(shí)踐中常用的一種表關(guān)聯(lián)方式,由于Hash Join實(shí)現(xiàn)會(huì)以右表做Build,且left Join不會(huì)做左右表的重新排序,在右表數(shù)據(jù)量很大時(shí)會(huì)造成執(zhí)行慢、消耗過多內(nèi)存資源等多個(gè)問題。本文以具體示例介紹哪些場景下可以用right join替代left join。

背景信息

AnalyticDB MySQL版默認(rèn)使用Hash Join進(jìn)行表關(guān)聯(lián)。Hash Join在實(shí)現(xiàn)時(shí)會(huì)用右表構(gòu)建哈希表,該過程會(huì)消耗大量資源,由于outer join(包括left join,right join)不同于inner join,從語義上不能交換左右表順序,因此在右表數(shù)據(jù)量大的場景下,會(huì)出現(xiàn)執(zhí)行慢、內(nèi)存資源消耗大的情況,在極端場景下(右表數(shù)據(jù)量很大)還會(huì)影響集群的性能,或執(zhí)行時(shí)直接報(bào)錯(cuò)Out of Memory Pool size pre cal。此時(shí),可以使用本章節(jié)提供的優(yōu)化方法來減少資源消耗。

使用場景

通過修改SQL語句或者加Hint的方式,可以將left join調(diào)整為right join,原left join中的左表會(huì)變?yōu)橛冶韥順?gòu)建哈希表。這時(shí)如果右表過大也會(huì)對(duì)性能有影響,因此,建議在left join左表較小,右表較大的場景下進(jìn)行優(yōu)化。

較小、很大的概念是相對(duì)的,和關(guān)聯(lián)列、集群資源等都有關(guān)系。在實(shí)踐中,我們可以通過Explain analyze查看執(zhí)行計(jì)劃的相關(guān)參數(shù),通過關(guān)注PeakMemory、WallTime等參數(shù)的變化來判斷是否應(yīng)該使用right join。

使用方法

通常有以下兩種方法可以把left join調(diào)整為right join:

  • 直接修改SQL,例如將a left join b on a.col1 = b.col2改為b right join a on a.col1 = b.col2

  • 通過加hint指定優(yōu)化器根據(jù)資源損耗把left join轉(zhuǎn)為right join。這種用法中,優(yōu)化器會(huì)根據(jù)左右表的估算大小來決定是否把left join轉(zhuǎn)為right join。使用方法如下:

    • 3.1.8及以上內(nèi)核版本的集群默認(rèn)開啟該特性。如關(guān)閉了該特性,可在SQL最前面加上hint:/*+O_CBO_RULE_SWAP_OUTER_JOIN=true*/手動(dòng)開啟該特性。

    • 3.1.8以下內(nèi)核版本的集群默認(rèn)關(guān)閉該特性。可在SQL最前面加上hint:/*+LEFT_TO_RIGHT_ENABLED=true*/開啟該特性。

說明 如何查看集群內(nèi)核版本,請參見如何查看實(shí)例版本信息。如需升級(jí)內(nèi)核版本,請聯(lián)系技術(shù)支持。

示例

如下示例中,nation是一個(gè)25行的小表,customer是一個(gè)15000000行的大表,通過explain analyze查看一條包含left join的SQL的執(zhí)行計(jì)劃。

explain analyze
SELECT
  COUNT(*)
FROM
  nation t1
  left JOIN customer t2 ON t1.n_nationkey = t2.c_nationkey

可以看到,進(jìn)行join計(jì)算的stage2的計(jì)劃如下。其中,Left Join這個(gè)算子中包含如下信息:

  • PeakMemory: 515MB (93.68%), WallTime: 4.34s (43.05%):PeakMemory的占比高達(dá)93.68%,可以判斷l(xiāng)eft join為整個(gè)SQL的性能瓶頸。

  • Left (probe) Input avg.: 0.52 rows;Right (build) Input avg.: 312500.00 rows:即右表為大表,左表為小表。

這種場景下,我們可以將left join轉(zhuǎn)為right join,來優(yōu)化這條SQL語句。

Fragment 2 [HASH]
    Output: 48 rows (432B), PeakMemory: 516MB, WallTime: 6.52us, Input: 15000025 rows (200.27MB); per task: avg.: 2500004.17 std.dev.: 2410891.74
    Output layout: [count_0_2]
    Output partitioning: SINGLE []
    Aggregate(PARTIAL)
    │   Outputs: [count_0_2:bigint]
    │   Estimates: {rows: ? (?)}
    │   Output: 96 rows (864B), PeakMemory: 96B (0.00%), WallTime: 88.21ms (0.88%)
    │   count_2 := count(*)
    └─ LEFT Join[(`n_nationkey` = `c_nationkey`)][$hashvalue, $hashvalue_0_4]
       │   Outputs: []
       │   Estimates: {rows: 15000000 (0B)}
       │   Output: 30000000 rows (200.27MB), PeakMemory: 515MB (93.68%), WallTime: 4.34s (43.05%)
       │   Left (probe) Input avg.: 0.52 rows, Input std.dev.: 379.96%
       │   Right (build) Input avg.: 312500.00 rows, Input std.dev.: 380.00%
       │   Distribution: PARTITIONED
       ├─ RemoteSource[3]
       │      Outputs: [n_nationkey:integer, $hashvalue:bigint]
       │      Estimates: 
       │      Output: 25 rows (350B), PeakMemory: 64KB (0.01%), WallTime: 63.63us (0.00%)
       │      Input avg.: 0.52 rows, Input std.dev.: 379.96%
       └─ LocalExchange[HASH][$hashvalue_0_4] ("c_nationkey")
          │   Outputs: [c_nationkey:integer, $hashvalue_0_4:bigint]
          │   Estimates: {rows: 15000000 (57.22MB)}
          │   Output: 30000000 rows (400.54MB), PeakMemory: 10MB (1.84%), WallTime: 1.81s (17.93%)
          └─ RemoteSource[4]
                 Outputs: [c_nationkey:integer, $hashvalue_0_5:bigint]
                 Estimates: 
                 Output: 15000000 rows (200.27MB), PeakMemory: 3MB (0.67%), WallTime: 191.32ms (1.90%)
                 Input avg.: 312500.00 rows, Input std.dev.: 380.00%
  • 通過修改SQL的方式實(shí)現(xiàn)left join to right join:

    SELECT
      COUNT(*)
    FROM
      customer t2
      right JOIN nation t1 ON t1.n_nationkey = t2.c_nationkey
  • 通過加Hint的方式實(shí)現(xiàn)left join to right join:

    • 3.1.8及以上內(nèi)核版本的集群執(zhí)行以下語句開啟該特性:

      /*+O_CBO_RULE_SWAP_OUTER_JOIN=true*/
      SELECT
        COUNT(*)
      FROM
        nation t1
        left JOIN customer t2 ON t1.n_nationkey = t2.c_nationkey
    • 3.1.8以下內(nèi)核版本的集群執(zhí)行以下語句開啟該特性:

      /*+LEFT_TO_RIGHT_ENABLED=true*/
      SELECT
        COUNT(*)
      FROM
        nation t1
        left JOIN customer t2 ON t1.n_nationkey = t2.c_nationkey

上述任意一種SQL,執(zhí)行explain analyze后可以看到,在執(zhí)行計(jì)劃中,left Join變?yōu)榱藃ight Join,可以判斷Hint是生效的。并且調(diào)整后PeakMemory的值為889 KB (3.31%),從515 MB下降到889 KB,已經(jīng)不是計(jì)算熱點(diǎn)。

Fragment 2 [HASH]
    Output: 96 rows (864B), PeakMemory: 12MB, WallTime: 4.27us, Input: 15000025 rows (200.27MB); per task: avg.: 2500004.17 std.dev.: 2410891.74
    Output layout: [count_0_2]
    Output partitioning: SINGLE []
    Aggregate(PARTIAL)
    │   Outputs: [count_0_2:bigint]
    │   Estimates: {rows: ? (?)}
    │   Output: 192 rows (1.69kB), PeakMemory: 456B (0.00%), WallTime: 5.31ms (0.08%)
    │   count_2 := count(*)
    └─ RIGHT Join[(`c_nationkey` = `n_nationkey`)][$hashvalue, $hashvalue_0_4]
       │   Outputs: []
       │   Estimates: {rows: 15000000 (0B)}
       │   Output: 15000025 rows (350B), PeakMemory: 889KB (3.31%), WallTime: 3.15s (48.66%)
       │   Left (probe) Input avg.: 312500.00 rows, Input std.dev.: 380.00%
       │   Right (build) Input avg.: 0.52 rows, Input std.dev.: 379.96%
       │   Distribution: PARTITIONED
       ├─ RemoteSource[3]
       │      Outputs: [c_nationkey:integer, $hashvalue:bigint]
       │      Estimates: 
       │      Output: 15000000 rows (200.27MB), PeakMemory: 3MB (15.07%), WallTime: 634.81ms (9.81%)
       │      Input avg.: 312500.00 rows, Input std.dev.: 380.00%
       └─ LocalExchange[HASH][$hashvalue_0_4] ("n_nationkey")
          │   Outputs: [n_nationkey:integer, $hashvalue_0_4:bigint]
          │   Estimates: {rows: 25 (100B)}
          │   Output: 50 rows (700B), PeakMemory: 461KB (1.71%), WallTime: 942.37us (0.01%)
          └─ RemoteSource[4]
                 Outputs: [n_nationkey:integer, $hashvalue_0_5:bigint]
                 Estimates: 
                 Output: 25 rows (350B), PeakMemory: 64KB (0.24%), WallTime: 76.34us (0.00%)
                 Input avg.: 0.52 rows, Input std.dev.: 379.96%