【用户分享】相同的 SQL 产生了不同执行计划,如何分析和优化?

这篇文章是 OBCE 大佬 @任仲禹 分享的一篇内容,示例租户虽是 Oracle 模式,但 MySQL 模式的租户也是一样的,大家不用在意这个兼容模式。

文中的示例 SQL 和执行计划都比较长,大家不用细看,所以做了一些简化。

重点是分析过程和解决方式,大家看完肯定都能够收获一些启发。

背景

问题描述

某系统测试OB上线前性能测试时,发现某条SQL执行时快时慢(慢时居多),与Oracle差异2倍以上:

  • Oracle中 3s 左右

  • OBoracle中 7s 左右

租户信息

  • OBoracle 4.2.1.9

  • 24C240G

  • 副本分布:1-1-1

  • PrimaryZone分布:Random (优先级均衡)

慢SQL语句

select
  *
from
  (
    select
      A.*,
      RowNum as Fast_RowNum
    from
      (
        /*sourceId:9b48a96b-ca31-415b-bb13-2c6890192d52sqlId:b99a8590-a548-271f-353d-41f4cd825583*/
        SELECT
          ...
          ...
          ...
        FROM
          TMPAYMENTSETTLEMENT
          LEFT JOIN BFNATIONALANDREGIONALDICT BFNATIONALANDREGIONALDICT ON TMPAYMENTSETTLEMENT.RECEIVINGCOUNTRY = BFNATIONALANDREGIONALDICT.ID
          LEFT JOIN BFADMINDIVISION BFADMINDIVISION ON TMPAYMENTSETTLEMENT.RECIPROCALCITY = BFADMINDIVISION.ID
          LEFT JOIN ...
        WHERE
          1 = 1
          and (
            ISTASK = '1'
            AND ISSHARE = '0'
            AND GENERATEDTIME = '1'
            AND BIZTYPE = '1'
            AND DOCSTATUS in ('1', '-2', '2', '-3', '-18')
            AND DOCSRC in ('1', '8', '12', '15')
            AND (
              TMPAYMENTSETTLEMENT.FK13 is null
              OR TMPAYMENTSETTLEMENT.FK13 = 'zfb'
              OR TMPAYMENTSETTLEMENT.FK14 = 'zfb'
              OR TMPAYMENTSETTLEMENT.FK15 = 'zfb'
              OR TMPAYMENTSETTLEMENT.APPLICANT = '3d64343f-43ba-4e3e-9bf0-e7d62381b729'
            )
          )
          /*otherwhere*/
          and (
            PAYUNIT in (
              select
                distinct aodata
              from
                (
                  select
                    distinct orgid aodata
                  from
                    gspuserposorg
                  where
                    userId = '3d64343f-43ba-4e3e-9bf0-e7d62381b729'
                    and orgTypeId = 'AdminOrg_Global'
                    and (
                      positionId in ('25e9529f-e9c9-4f37-9123-787fceb6da19')
                    )
                  union all
                  SELECT
                    ID aodata
                  from
                    BFAdminOrganization
                  where
                    ((treeinfo_path like '1859%'))
                ) User_TM_AdminOrg
            )
            and 1 = 1
          )
      ) A
    where
      RowNum < 1051
  )
where
  Fast_RowNum > 1000

 

SQL语句相关所有基表

(
  'TMPAYMENTSETTLEMENT',
  'BFNATIONALANDREGIONALDICT',
  'BFADMINDIVISION',
  'BFADMINORGANIZATION',
  'BFSETTLEMENTWAY',
  'BFCODEITEMS',
  'BFCURRENCY',
  'BFCASHFLOWTYPE',
  'BFBUSINESSMATTER',
  'BFBANKACCOUNTS',
  'BFBANK',
  'BFFINANCIALSUBJECTS',
  'BFFUNDSPROP',
  'BFACCOUNTINGORGANIZATION',
  'GSPUSERPOSORG',
  'BFADMINORGANIZATION'
)
11 个赞

分析过程

1. 慢SQL在ODC中执行

将慢 SELECT 在客户环境ODC中执行,发现耗时并不慢,执行耗时在0.5s左右。

2. 获取不慢时执行计划

获取慢 SQL 语句的逻辑执行计划。

=================================================================================================================================================================
|ID|OPERATOR                                                                                     |NAME                                    |EST.ROWS|EST.TIME(us)|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
|0 |COUNT                                                                                        |                                        |50      |30621       |
|1 |└─SUBPLAN SCAN                                                                               |VIEW1                                   |50      |30620       |
|2 |  └─LIMIT                                                                                    |                                        |50      |30620       |
|3 |    └─HASH RIGHT OUTER JOIN                                                                  |                                        |50      |30620       |
|4 |      ├─PX COORDINATOR                                                                       |                                        |197     |1242        |
|5 |      │ └─EXCHANGE OUT DISTR                                                                 |:EX10000                                |197     |1074        |
|6 |      │   └─TABLE RANGE SCAN                                                                 |BFCODEITEMS_JYBM(CODEITEMOFSET)         |197     |696         |
|7 |      └─NESTED-LOOP OUTER JOIN                                                               |                                        |50      |29266       |
|8 |        ├─HASH RIGHT OUTER JOIN                                                              |                                        |50      |28353       |
|9 |        │ ├─PX COORDINATOR                                                                   |                                        |182     |413         |
|10|        │ │ └─EXCHANGE OUT DISTR                                                             |:EX20000                                |182     |290         |
|11|        │ │   └─TABLE FULL SCAN                                                              |BFCURRENCY_PAY                          |182     |15          |
|12|        │ └─NESTED-LOOP OUTER JOIN                                                           |                                        |50      |27842       |
|13|        │   ├─NESTED-LOOP OUTER JOIN                                                         |                                        |50      |26926       |
|14|        │   │ ├─NESTED-LOOP OUTER JOIN                                                       |                                        |50      |26013       |
|15|        │   │ │ ├─NESTED-LOOP OUTER JOIN                                                     |                                        |50      |25100       |
|16|        │   │ │ │ ├─NESTED-LOOP OUTER JOIN                                                   |                                        |50      |24187       |
|17|        │   │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                                 |                                        |50      |23274       |
|18|        │   │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                               |                                        |50      |22362       |
|19|        │   │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                             |                                        |50      |21449       |
|20|        │   │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                           |                                        |50      |20536       |
|21|        │   │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                         |                                        |50      |19624       |
|22|        │   │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                       |                                        |50      |18711       |
|23|        │   │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                     |                                        |50      |17798       |
|24|        │   │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                   |                                        |50      |16886       |
|25|        │   │ │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                 |                                        |50      |15973       |
|26|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                               |                                        |50      |15061       |
|27|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                             |                                        |50      |14150       |
|28|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─HASH RIGHT OUTER JOIN                            |                                        |50      |13238       |
|29|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─PX COORDINATOR                                 |                                        |71      |484         |
|30|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─EXCHANGE OUT DISTR                           |:EX30000                                |71      |423         |
|31|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   └─TABLE RANGE SCAN                           |BFCODEITEMS_HKYT(CODEITEMOFSET)         |71      |287         |
|32|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HASH RIGHT OUTER JOIN                          |                                        |50      |12703       |
|33|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   ├─PX COORDINATOR                               |                                        |182     |413         |
|34|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   │ └─EXCHANGE OUT DISTR                         |:EX40000                                |182     |290         |
|35|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   │   └─TABLE FULL SCAN                          |BFCURRENCY_SXF                          |182     |15          |
|36|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   └─HASH RIGHT OUTER JOIN                        |                                        |50      |12192       |
|37|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     ├─PX COORDINATOR                             |                                        |182     |413         |
|38|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     │ └─EXCHANGE OUT DISTR                       |:EX50000                                |182     |290         |
|39|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     │   └─TABLE FULL SCAN                        |BFCURRENCY_C                            |182     |15          |
|40|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     └─HASH RIGHT OUTER JOIN                      |                                        |50      |11680       |
|41|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       ├─PX COORDINATOR                           |                                        |90      |297         |
|42|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       │ └─EXCHANGE OUT DISTR                     |:EX60000                                |90      |209         |
|43|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       │   └─TABLE FULL SCAN                      |BFCASHFLOWTYPE                          |90      |11          |
|44|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       └─HASH RIGHT OUTER JOIN                    |                                        |50      |11321       |
|45|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         ├─PX COORDINATOR                         |                                        |182     |413         |
|46|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         │ └─EXCHANGE OUT DISTR                   |:EX70000                                |182     |290         |
|47|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         │   └─TABLE FULL SCAN                    |BFCURRENCY                              |182     |15          |
|48|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         └─HASH RIGHT OUTER JOIN                  |                                        |50      |10810       |
|49|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │           ├─TABLE FULL SCAN                      |BFSETTLEMENTWAY                         |13      |5           |
|50|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │           └─HASH RIGHT OUTER JOIN                |                                        |50      |10781       |
|51|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │             ├─TABLE FULL SCAN                    |BFNATIONALANDREGIONALDICT               |253     |18          |
|52|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │             └─HASH RIGHT OUTER JOIN              |                                        |50      |10633       |
|53|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │               ├─TABLE FULL SCAN                  |BFFINANCIALSUBJECTS                     |5       |5           |
|54|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │               └─HASH RIGHT OUTER JOIN            |                                        |50      |10611       |
|55|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                 ├─TABLE FULL SCAN                |BFBUSINESSMATTER                        |8       |5           |
|56|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                 └─SUBPLAN SCAN                   |VIEW3                                   |50      |10587       |
|57|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                   └─LIMIT                        |                                        |50      |10587       |
|58|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                     └─NESTED-LOOP JOIN           |                                        |50      |10587       |
|59|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                       ├─PX COORDINATOR           |                                        |47      |8450        |
|60|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                       │ └─EXCHANGE OUT DISTR     |:EX80000                                |47      |6224        |
|61|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                       │   └─TABLE FULL SCAN      |TMPAYMENTSETTLEMENT                     |47      |1211        |
|62|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                       └─SUBPLAN SCAN             |VIEW2                                   |1       |45          |
|63|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                         └─MERGE UNION DISTINCT   |                                        |1       |45          |
|64|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                           ├─TABLE RANGE SCAN     |GSPUSERPOSORG(IDX_USERPOSORG_USERORGPOS)|1       |25          |
|65|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                           └─DISTRIBUTED TABLE GET|BFADMINORGANIZATION                     |1       |21          |
|66|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                            |BFADMINDIVISION                         |1       |18          |
|67|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                              |BFADMINORGANIZATION_100                 |1       |18          |
|68|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                |BFFUNDSPROP                             |1       |18          |
|69|        │   │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                  |BFCODEITEMS_YSGLLX                      |1       |18          |
|70|        │   │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                    |BFCODEITEMS_JJFL                        |1       |18          |
|71|        │   │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                      |BFCODEITEMS_ZCLX                        |1       |18          |
|72|        │   │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                        |BFCODEITEMS_YSLY                        |1       |18          |
|73|        │   │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                          |BFCODEITEMS                             |1       |18          |
|74|        │   │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                            |BFACCOUNTINGORGANIZATION                |1       |18          |
|75|        │   │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                              |BFCODEITEMS_SKRZHLX                     |1       |18          |
|76|        │   │ │ │ │ │ └─DISTRIBUTED TABLE GET                                                |BFCODEITEMS_FKXZ                        |1       |18          |
|77|        │   │ │ │ │ └─DISTRIBUTED TABLE GET                                                  |BFBANKACCOUNTS_CSH                      |1       |18          |
|78|        │   │ │ │ └─DISTRIBUTED TABLE GET                                                    |BFBANKACCOUNTS_SXF                      |1       |18          |
|79|        │   │ │ └─DISTRIBUTED TABLE GET                                                      |BFBANKACCOUNTS_300                      |1       |18          |
|80|        │   │ └─DISTRIBUTED TABLE GET                                                        |BFBANK_705                              |1       |18          |
|81|        │   └─DISTRIBUTED TABLE GET                                                          |BFBANKACCOUNTS_PAY                      |1       |18          |
|82|        └─DISTRIBUTED TABLE GET                                                              |BFBANK_1                                |1       |18          |
=================================================================================================================================================================

普通的分布式执行计划,暂未发现异常。

7 个赞

3. 获取用户侧SQL慢TRACE

通过获取用户侧实际慢的SQL查询AUDIT信息如下。

4. 获取慢时执行计划

通过 GV$PLAN_CACHE_PLAN_EXPLIAN 获取执行慢时的物理执行计划。

=====================================================================================================================================================================
|ID|OPERATOR                                                                                         |NAME                                    |EST.ROWS|EST.TIME(us)|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|0 |COUNT                                                                                            |                                        |50      |26308       |
|1 |└─SUBPLAN SCAN                                                                                   |VIEW1                                   |50      |26308       |
|2 |  └─LIMIT                                                                                        |                                        |50      |26308       |
|3 |    └─HASH RIGHT OUTER JOIN                                                                      |                                        |50      |26308       |
|4 |      ├─PX COORDINATOR                                                                           |                                        |197     |1242        |
|5 |      │ └─EXCHANGE OUT DISTR                                                                     |:EX10000                                |197     |1074        |
|6 |      │   └─TABLE RANGE SCAN                                                                     |BFCODEITEMS_JYBM(CODEITEMOFSET)         |197     |696         |
|7 |      └─NESTED-LOOP OUTER JOIN                                                                   |                                        |50      |24953       |
|8 |        ├─HASH RIGHT OUTER JOIN                                                                  |                                        |50      |24041       |
|9 |        │ ├─PX COORDINATOR                                                                       |                                        |182     |413         |
|10|        │ │ └─EXCHANGE OUT DISTR                                                                 |:EX20000                                |182     |290         |
|11|        │ │   └─TABLE FULL SCAN                                                                  |BFCURRENCY_PAY                          |182     |15          |
|12|        │ └─NESTED-LOOP OUTER JOIN                                                               |                                        |50      |23529       |
|13|        │   ├─NESTED-LOOP OUTER JOIN                                                             |                                        |50      |22614       |
|14|        │   │ ├─NESTED-LOOP OUTER JOIN                                                           |                                        |50      |21701       |
|15|        │   │ │ ├─NESTED-LOOP OUTER JOIN                                                         |                                        |50      |20788       |
|16|        │   │ │ │ ├─NESTED-LOOP OUTER JOIN                                                       |                                        |50      |19875       |
|17|        │   │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                                     |                                        |50      |18962       |
|18|        │   │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                                   |                                        |50      |18050       |
|19|        │   │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                                 |                                        |50      |17137       |
|20|        │   │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                               |                                        |50      |16224       |
|21|        │   │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                             |                                        |50      |15312       |
|22|        │   │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                           |                                        |50      |14399       |
|23|        │   │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                         |                                        |50      |13486       |
|24|        │   │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                       |                                        |50      |12573       |
|25|        │   │ │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                     |                                        |50      |11661       |
|26|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                   |                                        |50      |10749       |
|27|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─NESTED-LOOP OUTER JOIN                                 |                                        |50      |9837        |
|28|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─HASH RIGHT OUTER JOIN                                |                                        |50      |8925        |
|29|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─PX COORDINATOR                                     |                                        |71      |484         |
|30|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─EXCHANGE OUT DISTR                               |:EX30000                                |71      |423         |
|31|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   └─TABLE RANGE SCAN                               |BFCODEITEMS_HKYT(CODEITEMOFSET)         |71      |287         |
|32|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HASH RIGHT OUTER JOIN                              |                                        |50      |8391        |
|33|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   ├─PX COORDINATOR                                   |                                        |182     |413         |
|34|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   │ └─EXCHANGE OUT DISTR                             |:EX40000                                |182     |290         |
|35|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   │   └─TABLE FULL SCAN                              |BFCURRENCY_SXF                          |182     |15          |
|36|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │   └─HASH RIGHT OUTER JOIN                            |                                        |50      |7879        |
|37|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     ├─PX COORDINATOR                                 |                                        |253     |548         |
|38|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     │ └─EXCHANGE OUT DISTR                           |:EX50000                                |253     |385         |
|39|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     │   └─TABLE FULL SCAN                            |BFNATIONALANDREGIONALDICT               |253     |18          |
|40|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │     └─HASH RIGHT OUTER JOIN                          |                                        |50      |7202        |
|41|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       ├─PX COORDINATOR                               |                                        |182     |413         |
|42|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       │ └─EXCHANGE OUT DISTR                         |:EX60000                                |182     |290         |
|43|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       │   └─TABLE FULL SCAN                          |BFCURRENCY_C                            |182     |15          |
|44|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │       └─HASH RIGHT OUTER JOIN                        |                                        |50      |6691        |
|45|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         ├─PX COORDINATOR                             |                                        |182     |413         |
|46|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         │ └─EXCHANGE OUT DISTR                       |:EX70000                                |182     |290         |
|47|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         │   └─TABLE FULL SCAN                        |BFCURRENCY                              |182     |15          |
|48|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │         └─HASH RIGHT OUTER JOIN                      |                                        |50      |6179        |
|49|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │           ├─PX COORDINATOR                           |                                        |90      |297         |
|50|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │           │ └─EXCHANGE OUT DISTR                     |:EX80000                                |90      |209         |
|51|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │           │   └─TABLE FULL SCAN                      |BFCASHFLOWTYPE                          |90      |11          |
|52|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │           └─HASH RIGHT OUTER JOIN                    |                                        |50      |5820        |
|53|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │             ├─PX COORDINATOR                         |                                        |13      |74          |
|54|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │             │ └─EXCHANGE OUT DISTR                   |:EX90000                                |13      |53          |
|55|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │             │   └─TABLE FULL SCAN                    |BFSETTLEMENTWAY                         |13      |5           |
|56|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │             └─HASH RIGHT OUTER JOIN                  |                                        |50      |5722        |
|57|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │               ├─PX COORDINATOR                       |                                        |5       |16          |
|58|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │               │ └─EXCHANGE OUT DISTR                 |:EX100000                               |5       |12          |
|59|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │               │   └─TABLE FULL SCAN                  |BFFINANCIALSUBJECTS                     |5       |5           |
|60|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │               └─HASH RIGHT OUTER JOIN                |                                        |50      |5688        |
|61|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                 ├─PX COORDINATOR                     |                                        |8       |21          |
|62|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                 │ └─EXCHANGE OUT DISTR               |:EX110000                               |8       |16          |
|63|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                 │   └─TABLE FULL SCAN                |BFBUSINESSMATTER                        |8       |5           |
|64|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                 └─SUBPLAN SCAN                       |VIEW3                                   |50      |5648        |
|65|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                   └─LIMIT                            |                                        |50      |5648        |
|66|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                     └─NESTED-LOOP JOIN               |                                        |50      |5647        |
|67|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                       ├─TABLE FULL SCAN              |TMPAYMENTSETTLEMENT                     |47      |1211        |
|68|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                       └─PX COORDINATOR               |                                        |1       |45          |
|69|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                         └─EXCHANGE OUT DISTR         |:EX120000                               |1       |45          |
|70|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                           └─SUBPLAN SCAN             |VIEW2                                   |1       |45          |
|71|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                             └─MERGE UNION DISTINCT   |                                        |1       |45          |
|72|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                               ├─TABLE RANGE SCAN     |GSPUSERPOSORG(IDX_USERPOSORG_USERORGPOS)|1       |25          |
|73|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │                               └─DISTRIBUTED TABLE GET|BFADMINORGANIZATION                     |1       |21          |
|74|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                |BFADMINDIVISION                         |1       |18          |
|75|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                  |BFADMINORGANIZATION_100                 |1       |18          |
|76|        │   │ │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                    |BFFUNDSPROP                             |1       |18          |
|77|        │   │ │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                      |BFCODEITEMS_YSGLLX                      |1       |18          |
|78|        │   │ │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                        |BFCODEITEMS_JJFL                        |1       |18          |
|79|        │   │ │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                          |BFCODEITEMS_ZCLX                        |1       |18          |
|80|        │   │ │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                            |BFCODEITEMS_YSLY                        |1       |18          |
|81|        │   │ │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                              |BFCODEITEMS                             |1       |18          |
|82|        │   │ │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                                |BFACCOUNTINGORGANIZATION                |1       |18          |
|83|        │   │ │ │ │ │ │ └─DISTRIBUTED TABLE GET                                                  |BFCODEITEMS_SKRZHLX                     |1       |18          |
|84|        │   │ │ │ │ │ └─DISTRIBUTED TABLE GET                                                    |BFCODEITEMS_FKXZ                        |1       |18          |
|85|        │   │ │ │ │ └─DISTRIBUTED TABLE GET                                                      |BFBANKACCOUNTS_CSH                      |1       |18          |
|86|        │   │ │ │ └─DISTRIBUTED TABLE GET                                                        |BFBANKACCOUNTS_SXF                      |1       |18          |
|87|        │   │ │ └─DISTRIBUTED TABLE GET                                                          |BFBANKACCOUNTS_300                      |1       |18          |
|88|        │   │ └─DISTRIBUTED TABLE GET                                                            |BFBANK_705                              |1       |18          |
|89|        │   └─DISTRIBUTED TABLE GET                                                              |BFBANKACCOUNTS_PAY                      |1       |18          |
|90|        └─DISTRIBUTED TABLE GET                                                                  |BFBANK_1                                |1       |18          |
=====================================================================================================================================================================

线索:同一条SQL的执行计划不一致。

可以看到,两者的执行计划不一致:

  • 执行快时:执行计划有82个算子

  • 执行慢时,执行计划有90个算子

  • 截取快的SQL部分算子:

  • 截取慢的SQL部分算子:

分析

1.两者的该部分执行计划都是语义上相同:

  • 都需先做 TMPAYMENTSETTLEMENT 与 VIEW2 的NLJ。

  • 然后再做上述算子与 BFBUSINESSMATTER 的HASH OUT JOIIN。

2.但是可以明显看到慢的计划中:

  • 58号算子存在 EXCHANGE OUT 算子,也就是全表扫描完BFFINANCIALSUBJECTS的数据需要吐给上层节点(该节点存在不同的OBSERVER节点或线程)

  • 62号算子也是同理,访问完 BFBUSINESSMATTER 表的数据后需要将数据发送给上层节点。

3.为什么有这种现象,猜测大可能的原因是不同表的Leader分布在不同。

5. 检查Leader分布

我们继续分析下各个基表的Leader分布,查询语句如下

select DATABASE_NAME,TABLE_NAME,TABLE_TYPE,ZONE,SVR_IP,ROLE  from dba_ob_table_locations where role = 'LEADER' and database_name = 'RENZYTEST1' and  table_name in (
  'TMPAYMENTSETTLEMENT',
  'BFNATIONALANDREGIONALDICT',
  'BFADMINDIVISION',
  'BFADMINORGANIZATION',
  'BFSETTLEMENTWAY',
  'BFCODEITEMS',
  'BFCURRENCY',
  'BFCASHFLOWTYPE',
  'BFBUSINESSMATTER',
  'BFBANKACCOUNTS',
  'BFBANK',
  'BFFINANCIALSUBJECTS',
  'BFFUNDSPROP',
  'BFACCOUNTINGORGANIZATION',
  'GSPUSERPOSORG',
  'BFADMINORGANIZATION'
)
order by zone;
+---------------+---------------------------+------------+-------+-------------+--------+
| DATABASE_NAME | TABLE_NAME                | TABLE_TYPE | ZONE  | SVR_IP      | ROLE   |
+---------------+---------------------------+------------+-------+-------------+--------+
| RENZYTEST1    | TMPAYMENTSETTLEMENT       | USER TABLE | zone1 | 10.18.38.54 | LEADER |
| RENZYTEST1    | BFFUNDSPROP               | USER TABLE | zone1 | 10.18.38.54 | LEADER |
| RENZYTEST1    | GSPUSERPOSORG             | USER TABLE | zone2 | 10.18.38.55 | LEADER |
| RENZYTEST1    | BFSETTLEMENTWAY           | USER TABLE | zone2 | 10.18.38.55 | LEADER |
| RENZYTEST1    | BFNATIONALANDREGIONALDICT | USER TABLE | zone2 | 10.18.38.55 | LEADER |
| RENZYTEST1    | BFFINANCIALSUBJECTS       | USER TABLE | zone2 | 10.18.38.55 | LEADER |
| RENZYTEST1    | BFBUSINESSMATTER          | USER TABLE | zone2 | 10.18.38.55 | LEADER |
| RENZYTEST1    | BFADMINORGANIZATION       | USER TABLE | zone2 | 10.18.38.55 | LEADER |
| RENZYTEST1    | BFADMINDIVISION           | USER TABLE | zone2 | 10.18.38.55 | LEADER |
| RENZYTEST1    | BFACCOUNTINGORGANIZATION  | USER TABLE | zone3 | 10.18.38.56 | LEADER |
| RENZYTEST1    | BFCURRENCY                | USER TABLE | zone3 | 10.18.38.56 | LEADER |
| RENZYTEST1    | BFCODEITEMS               | USER TABLE | zone3 | 10.18.38.56 | LEADER |
| RENZYTEST1    | BFBANKACCOUNTS            | USER TABLE | zone3 | 10.18.38.56 | LEADER |
| RENZYTEST1    | BFBANK                    | USER TABLE | zone3 | 10.18.38.56 | LEADER |
| RENZYTEST1    | BFCASHFLOWTYPE            | USER TABLE | zone3 | 10.18.38.56 | LEADER |
+---------------+---------------------------+------------+-------+-------------+--------+
15 rows in set (0.157 sec)

可以看到,上述执行计划章节中部分差异算子涉及的基表 Leader 分布确实不同:

  • Leader在55节点:BFFINANCIALSUBJECTS,BFBUSINESSMATTER

  • Leader在54节点:TMPAYMENTSETTLEMENT

由此可知:因为涉及到跨节点分布式访问多表,SQL在不同节点生成的执行计划是不一致的,所以其耗时效率也是不一致的。

6. 耗时差异对比分析

继续多次执行该条SQL,获取下耗时分布:

可以看到发往不同svr_ip的SQL,其SQL一样(SQL_ID相同),但是其产生的执行计划确截然不同(通过Plan_id可以获知)。

问题原因

通过分析过程,我们可以获知问题原因如下:

  • 为何多次执行同一条SQL,其耗时差异却不一致?

    • 因为该条SQL是分布式执行计划,发往了不同observer节点上,导致了执行计划不一致,从而SQL执行速度不一致。
  • 为何一条SQL会发往不同observer节点?

    • 因为租户PrimaryZone为Random,即副本优先级均衡分布的模式,各个节点上都承载了部分表的Leader节点,以均衡业务压力。
  • 为何发往不同observer节点后,执行计划会不同?

    • OB是分布式数据库,优化器会自动根据查询和数据(Leader)的物理分布,生成分布式执行计划。

结论与优化

上述问题在分布式数据库中无法避免,那面临该种CASE时,OB如何优化?

Hint优化

在业务SQL中加并发HINT,例如代码中最外层投影中加上 SELECT /*+ PARALLEL(9) */ ,即可充分利用分布式的并行查询优势。

  • 该点经实际验证,可将慢SQL从7s优化到2-3s内。

  • 但该优化点对业务有一定业务侵入性。(需要代码中给SQL加HINT)

TableGroup优化

对于Hint也无法解决,或者需要深度SQL优化的场景,OB提供了表组[注1]功能进行优化,。

  • 表组(Table Group)是一个逻辑概念,表示一组表的集合,即将一组表的Leader集中在一个OBserver节点上。默认情况下,不同表之间的数据副本Leader是随机分布的。使用 Table Group 将一组表Leader分布在相同的节点上,以减少跨节点的数据交互。

优化步骤

# 创建表组
CREATE TABLEGROUP tg_sk1 SHARDING = 'NONE';
# 将SQL涉及的基表添加到表组中
ALTER TABLEGROUP tg_sk1 ADD TMPAYMENTSETTLEMENT,BFNATIONALANDREGIONALDICT,BFADMINDIVISION,BFADMINORGANIZATION,BFSETTLEMENTWAY,BFCODEITEMS,BFCURRENCY,BFCASHFLOWTYPE,BFBUSINESSMATTER,BFBANKACCOUNTS,BFBANK,BFFINANCIALSUBJECTS,BFFUNDSPROP,BFACCOUNTINGORGANIZATION,GSPUSERPOSORG,BFADMINORGANIZATION;

再次检查Leader分布

+---------------+---------------------------+------------+-------+-------------+----------------+--------+
| DATABASE_NAME | TABLE_NAME                | TABLE_TYPE | ZONE  | SVR_IP      | PARTITION_NAME | ROLE   |
+---------------+---------------------------+------------+-------+-------------+----------------+--------+
| RENZYTEST1    | BFACCOUNTINGORGANIZATION  | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | TMPAYMENTSETTLEMENT       | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | GSPUSERPOSORG             | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFSETTLEMENTWAY           | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFNATIONALANDREGIONALDICT | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFFUNDSPROP               | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFFINANCIALSUBJECTS       | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFCURRENCY                | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFCODEITEMS               | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFBUSINESSMATTER          | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFBANKACCOUNTS            | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFBANK                    | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFCASHFLOWTYPE            | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFADMINORGANIZATION       | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
| RENZYTEST1    | BFADMINDIVISION           | USER TABLE | zone2 | 10.18.38.55 | NULL           | LEADER |
+---------------+---------------------------+------------+-------+-------------+----------------+--------+

再次分析耗时情况

多次执行该SQL,可以看到该SQL无论发往哪个节点上,执行耗时基本稳定在400ms左右。

  • 因为所有的基表Leader都在一个节点上,减少了分布式算子的开销(如下图中,PLAN_TYPE基本为1、2,未再有3)。

    • 1为本地执行计划,2为远程执行计划,3为分布式执行计划,其原理不展开赘述。
  • 为何会有3s,1.8s,1.7s的SQL执行,相同SQL_ID执行在不同OBserver上执行时,第一次执行时都会进行硬解析,去生成执行计划缓存,可以看到各节点上后续的执行耗时基本能稳定。

结果

  • 该SQL在Oracle中执行为 3s。

  • 该SQL在OBoracle中执行最慢为 7s。

    • 经过 HINT 优化,可优化至 2-3s。

    • 经过表组优化,可优化至0.4s

  • 解决方式:已为该SQL涉及的基表添加表组 tg_sk1,业务侧无需调整,减少业务侵入。

参考资料

10 个赞