成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

OB 運維 | 1000s->10s OceanBase 標量子查詢改寫案例

運維
重點是 10、14 兩個算子,對應的 2 個標量子查詢除了和外表關聯外,本身內部還有 o、k 這 2 張表關聯,這兩張表要做多少次關聯?13萬次! 很明顯這里效率會很低。

1.問題描述

  • 數據庫版本:OceanBase 3.2.3.3

下面這個 SQL 執行超過 1000 秒……

本文用這個例子,談談標量子查詢慢的原因和優化方法。

select
  rq.processinstid processinstid,
  rq.question_id questionId,
  rq.question_no questionNo,
  to_char(rq.rev_start_date, 'yyyy-MM-dd') revStartDate,
  (
    select
      e.name
    from
      e
    where
      e.category_code = 'REV_SOURCE'
      and e.code = rq.rev_source
  ) revSource,
  (
    select
      e.name
    from
      e
    where
      e.category_code = 'QUESTION_TYPE'
      and e.code = rq.question_type
  ) questionType,
  rq.question_summary questionSummary,
  rq.question_desc questionDesc,
  to_char(rq.question_discover_date, 'yyyy-MM-dd') questionDiscoverDate,
  rq.aud_project_type audProjectType,
  (
    select
      d.dept_name
    from
      d
    where
      d.dept_id = rq.check_dept
  ) checkDept,
  (
    select
      to_char(wm_concat(distinct(k.org_name)))
    from
      o,
      k
    where
      o.question_id = rq.question_id
      and o.ASC_ORG = k.org_id
      and o.REFORM_TYPE = '0'
  ) ascOrg,
  (
    select
      to_char(wm_concat(distinct(k.dept_name)))
    from
      o,
      fnd_dept_t k
    where
      o.question_id = rq.question_id
      and o.MAIN_REV_DEPT = k.dept_id
      and o.REFORM_TYPE = '0'
  ) mainRevDept,
  (
    select
      e.name
    from
      e
    where
      e.category_code = 'REV_FINISH_STATE'
      and e.code = rq.rev_finish_state
  ) revFinishState,
  to_char(rq.compliance_date, 'yyyy-MM-dd') complianceDATE
from
  rq
  left join REM_QUESTION_PLAN_T t on rq.question_id = t.question_id
  left join fnd_org_t org on t.ASC_ORG = org.org_id
where
  1 = 1
  and rq.asc_org is null
  and (
    t.asc_org in (
      select
        f.org_id
      from
        f
      where
        f.org_type = 'G'
    )
    or rq.created_by_org in (
      select
        f.org_id
      from
        f
      where
        f.org_type = 'G'
    )
  )
  and rq.company_type = 'G';

2.分析過程

執行計劃如下:

===========================================================
|ID|OPERATOR          |NAME           |EST. ROWS|COST     |
-----------------------------------------------------------
|0 |SUBPLAN FILTER    |               |6283     |788388847|
|1 | SUBPLAN FILTER   |               |6283     |1325483  |
|2 |  HASH OUTER JOIN |               |8377     |210530   |
|3 |   TABLE SCAN     |RQ             |7966     |77932    |
|4 |   TABLE SCAN     |T              |152919   |59150    |
|5 |  TABLE SCAN      |F              |440      |2763     |
|6 |  TABLE SCAN      |F              |440      |2763     |
|7 | TABLE SCAN       |E(SYS_C0011218)|1        |92       |
|8 | TABLE SCAN       |E(SYS_C0011218)|1        |92       |
|9 | TABLE GET        |D              |1        |46       |
|10| SCALAR GROUP BY  |               |1        |62483    |
|11|  NESTED-LOOP JOIN|               |1        |62483    |
|12|   TABLE SCAN     |O              |1        |62468    |
|13|   TABLE GET      |K              |1        |28       |
|14| SCALAR GROUP BY  |               |1        |62483    |
|15|  NESTED-LOOP JOIN|               |1        |62483    |
|16|   TABLE SCAN     |O              |1        |62468    |
|17|   TABLE GET      |K              |1        |27       |
|18| TABLE SCAN       |E(SYS_C0011218)|1        |92       |
===========================================================

每個子算子的成本都不高,但總成本很高!

下面結合 SQL 語法語義進行解讀。

首先,這個 SQL 從語法上分兩部分:

  1. 標量子查詢,即投影部分的子查詢。
  2. 外部查詢,即 FROM 子句的關聯查詢和子查詢。

因此,這個 SQL 的執行邏輯是(也就是執行計劃里的 0 號 SUBPLAN FILTER 算子):

  1. 先執行外部查詢,得到 結果集 r(執行計劃中的 1-6 號算子)。
  2. 再執行標量子查詢,從 結果集 r 中取一行數據,帶入到標量子查詢中執行(執行計劃中的 7-18 號算子)。
  3. 重復上一步,直到循環取完最后一行數據。

為了定位 SQL 到底慢在哪一步?讓我們繼續拆解。

  • 先拆出外部查詢(即對應的 1-6 號算子部分),單獨執行很快得到結果 13 萬行,也就意味著所有標量子查詢都需要執行 13 萬次。
  • 從執行計劃來看,7、8、9、18 號算子對應的 4 個標量子查詢都可以走索引,效率較高。只保留外部查詢和這 4 個標量子查詢,執行耗時很短。
  • 重點是 10、14 兩個算子,對應的 2 個標量子查詢除了和外表關聯外,本身內部還有 o、k 這 2 張表關聯,這兩張表要做多少次關聯?13萬次! 很明顯這里效率會很低。

SQL 中 10、14 兩個算子對應的標量子查詢如下,還可以再拆解 SQL,單獨只做一次 、k 表的關聯查詢(如下標黃部分)要 200 毫秒:

select
xxx,
(
    select
      to_char(wm_concat(distinct(k.org_name)))
    from
      REM_QUESTION_PLAN_T o,
      fnd_org_t k
    where
      o.question_id = rq.question_id
      and o.ASC_ORG = k.org_id
      and o.REFORM_TYPE = '0'
  ) ascOrg,
  (
    select
      to_char(wm_concat(distinct(k.dept_name)))
    from
      REM_QUESTION_PLAN_T o,
      fnd_dept_t k
    where
      o.question_id = rq.question_id
      and o.MAIN_REV_DEPT = k.dept_id
      and o.REFORM_TYPE = '0'
  ) mainRevDept,
  xxx
  from t(外部查詢,結果有 13 萬行);

3.結論

標量子查詢的執行計劃只能是循環嵌套連接,也就是 SUBPLAN FILTER 算子(等同于 NESTED-LOOP JOIN 執行邏輯),它的執行效率取決于兩個因素:

  • 外部查詢的結果集大小
  • 子查詢的效率

因此只有當外部查詢結果集不大,并且子查詢的關聯字段有高效索引時,執行效率才高。如果關聯字段沒有索引,優化器也沒法像 JOIN 語法一樣使用 HASH JOIN 算子,執行效率很差。

在上面這個慢 SQL 中,有兩個標量子查詢不只和外表關聯,它內部還有關聯查詢,所以即使關聯字段有索引,子查詢單次執行的效率也受限,再加上要執行 13 萬次,這個耗時就長了。所以這個 SQL 只能改寫成 LEFT JOIN 來優化,這也是標量子查詢的標準優化方法。

4.優化方案

這個 SQL 的標量子查詢中有聚合函數,應該先 GROUP BY 聚合后再和外表關聯,SQL(局部)改寫如下:

with t1 as (
  select
    o.question_id,
    to_char(wm_concat(distinct(k.org_name))) as org_name
  from
    REM_QUESTION_PLAN_T o,
    fnd_org_t k
  where
    o.ASC_ORG = k.org_id
    and o.REFORM_TYPE = '0'
  group by
    o.question_id
),
t2 as (
  select
    o.question_id,
    to_char(wm_concat(distinct(k.dept_name))) as dept_name
  from
    REM_QUESTION_PLAN_T o,
    fnd_dept_t k
  where
    o.MAIN_REV_DEPT = k.dept_id
    and o.REFORM_TYPE = '0'
  group by
    o.question_id
)
select
xxx,
t1.org_name as ascOrg,
t2.dept_name as mainRevDept,
xxx
  from t(外部查詢,結果有 13 萬行)
  left join t1 on t.question_id=t1.question_id
  left join t2 on t.question_id=t2.question_id;

改寫后的執行計劃如下(變成了使用 HASH OUTER JOIN 算法),可以看到。

成本 7.88 億降到了 365 萬,執行耗時降到 10 秒!

=============================================================
|ID|OPERATOR              |NAME           |EST. ROWS|COST   |
-------------------------------------------------------------
|0 |SUBPLAN FILTER        |               |6318     |3653489|
|1 | MERGE GROUP BY       |               |6318     |1636701|
|2 |  SORT                |               |6318     |1632074|
|3 |   SUBPLAN FILTER     |               |6318     |1613799|
|4 |    HASH OUTER JOIN   |               |8424     |492531 |
|5 |     HASH OUTER JOIN  |               |8377     |331672 |
|6 |      MERGE OUTER JOIN|               |7966     |198317 |
|7 |       TABLE SCAN     |RQ             |7966     |77932  |
|8 |       SUBPLAN SCAN   |T2             |2351     |119098 |
|9 |        MERGE GROUP BY|               |2351     |119062 |
|10|         SORT         |               |2352     |118658 |
|11|          HASH JOIN   |               |2352     |113818 |
|12|           TABLE SCAN |K              |22268    |8614   |
|13|           TABLE SCAN |O              |76460    |60075  |
|14|      TABLE SCAN      |T              |152919   |59150  |
|15|     SUBPLAN SCAN     |T1             |76415    |118014 |
|16|      HASH JOIN       |               |76415    |116865 |
|17|       TABLE SCAN     |K              |7033     |2721   |
|18|       TABLE SCAN     |O              |76460    |60075  |
|19|    TABLE SCAN        |F              |440      |2763   |
|20|    TABLE SCAN        |F              |440      |2763   |
|21| TABLE SCAN           |E(SYS_C0011218)|1        |92     |
|22| TABLE SCAN           |E(SYS_C0011218)|1        |92     |
|23| TABLE GET            |D              |1        |46     |
|24| TABLE SCAN           |E(SYS_C0011218)|1        |92     |
=============================================================

作者:胡呈清,愛可生 DBA 團隊成員,擅長故障分析、性能優化,個人博客:[簡書 | 輕松的魚]

責任編輯:武曉燕 來源: 愛可生開源社區
相關推薦

2024-04-01 09:48:49

GreatSQL語句NULL

2025-02-07 11:08:03

OceanBase集群NFS

2024-05-31 13:23:19

OceanBase單機版架構

2023-08-16 15:03:36

廣告數據庫

2022-09-27 08:40:44

慢查詢MySQL定位優化

2025-02-11 07:42:50

DeepSeekPPT學術

2019-11-28 19:52:00

華為暢享10S

2019-11-28 19:06:00

華為暢享10S

2013-05-23 09:45:54

2022-11-13 17:48:33

JavaSQL

2019-12-05 18:59:00

華為暢享10S

2019-12-05 19:04:00

2009-07-01 11:55:00

國家部委IT運維管理體系

2019-12-05 18:58:00

華為暢享10S

2019-12-05 19:09:00

華為暢享10S

2019-12-05 19:48:00

華為暢享10S

2019-12-05 19:10:00

華為暢享10S

2019-12-05 19:01:00

華為暢享10S

2019-12-05 20:05:00

華為暢享10S

2019-11-28 19:11:00

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲九九色 | 91xxx在线观看 | 91社影院在线观看 | 岛国av免费观看 | 久艹av | 久久蜜桃精品 | 在线观看黄色电影 | 不卡一区| 国产日韩欧美中文 | 中文字幕观看 | 羞羞网站在线观看 | 欧美精品一区二区在线观看 | 精品视频在线观看 | 日本精品一区二区 | 亚洲精品视频一区 | 欧美 日韩 国产 成人 在线 | 国产一区二区中文字幕 | 国产美女福利在线观看 | 国产精品日日摸夜夜添夜夜av | 日韩av手机在线观看 | 91一区二区三区在线观看 | 国产日产精品一区二区三区四区 | 午夜合集| 久久久无码精品亚洲日韩按摩 | 91xxx在线观看 | 久久综合色综合 | 亚洲国产欧美国产综合一区 | 中文字幕在线国产 | 青青草综合网 | 在线播放一区二区三区 | 午夜国产羞羞视频免费网站 | 欧美xxxx日本 | 日日操夜夜干 | 欧美久久一区二区三区 | 日日天天 | 国产免费一区 | 亚洲高清视频一区 | 久久久久香蕉视频 | 欧美天堂一区 | 国产在线一区二区三区 | 欧美9999 |