• 记录朋友的一次调优经历及我的疑问


    以下是一位朋友的一次调优SQL的经历,有很多精彩的地方,仅仅为了记录,后面附上我的疑问,一并贴在下面:

    主要环境如下:

    SQL> select * from v$version;

    BANNER
    -------------------------------------------------------------------------------

    Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production

    4节点 HPUX RAC OLAP 环境

    SQL> show parameter db_block_size

    NAME                                 TYPE                              VALUE
    ------------------------------------ --------------------------------- ------
    db_block_size                        integer                           16384
    SQL> show parameter db_file

    NAME                                 TYPE                              VALUE
    ------------------------------------ --------------------------------- ------
    db_file_multiblock_read_count        integer

    ETL开发人员找我调查一个long running的JOB,该JOB已经跑了7小时了还没跑完。

    那个JOB 是一个insert into ... select ..... 语句。insert 肯定不会7小时还
    未完成,所以,这里主要的调整应该关注 select 部分

    select部分的SQL语句如下,这是一个接近400行的SQL,大家不要头晕哈,可以直
    接跳过这个SQL语句,看我下面的分析

    SELECT  ACTVY_SKID,
                          FUND_SKID,
                          PRMTN_SKID,
                          PROD_SKID,
                          DATE_SKID,
                          ACCT_SKID,
                          BUS_UNIT_SKID,
                          FY_DATE_SKID,
                          ESTMT_VAR_COST_AMT,
                          ESTMT_FIXED_COST_AMT,
                          REVSD_ESTMT_VAR_COST_AMT,
                          ACTL_VAR_COST_AMT,
                          ACTL_FIXED_COST_AMT,
                          COST_PLAN_AMT,
                          COST_CMMT_AMT,
                          COST_BOOK_AMT,
                          ESTMT_COST_OVRRD_AMT,
                          LA_TOT_BOOK_AMT,
                          MANUL_COST_OVRRD_AMT,
                          ACTL_COST_AMT
                   FROM   (SELECT ACTVY_SKID,
           FUND_SKID,
           PROD_SKID,
           PRMTN_SKID,
           DATE_SKID,
           ACCT_SKID,
           BUS_UNIT_SKID,
           FY_DATE_SKID,
           ESTMT_VAR_COST_AMT,
           ESTMT_FIXED_COST_AMT,
           REVSD_ESTMT_VAR_COST_AMT,
           0 as ACTL_COST_AMT,
           ACTL_VAR_COST_AMT,
           ACTL_FIXED_COST_AMT,
           MANUL_COST_OVRRD_AMT,
           ESTMT_COST_OVRRD_AMT,
           COST_BOOK_AMT,
           -- Updated by Luke for QC3369
           -- If the committed amount on Activity level <0 then return 0
           (CASE
             WHEN SUM(ESTMT_COST_OVRRD_AMT - ACTL_VAR_COST_AMT -
                      ACTL_FIXED_COST_AMT) OVER(PARTITION BY ACTVY_SKID) < 0 THEN
              0
             ELSE
              COST_CMMT_AMT
           END) AS COST_CMMT_AMT,
           -- Updated by Luke for QC3369
           (CASE
             WHEN SUM(ESTMT_COST_OVRRD_AMT - ACTL_VAR_COST_AMT -
                      ACTL_FIXED_COST_AMT) OVER(PARTITION BY ACTVY_SKID) < 0 THEN
              0
             ELSE
              COST_PLAN_AMT
           END) AS COST_PLAN_AMT,
           LA_TOT_BOOK_AMT
      FROM (SELECT ACTVY_SKID,
                   FUND_SKID,
                   PROD_SKID,
                   PRMTN_SKID,
                   DATE_SKID,
                   ACCT_SKID,
                   BUS_UNIT_SKID,
                   FY_DATE_SKID,
                   ESTMT_VAR_COST_AMT,
                   ESTMT_FIXED_COST_AMT,
                   REVSD_ESTMT_VAR_COST_AMT,
                   ACTL_VAR_COST_AMT,
                   ACTL_FIXED_COST_AMT,
                   MANUL_COST_OVRRD_AMT,
                   (CASE
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'E' THEN
                      ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'R' THEN
                      ESTMT_FIXED_COST_AMT +
                      DECODE(REVSD_BPT_COST_AMT,
                             0,
                             REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                             REVSD_BPT_COST_AMT) --BPT Revised Cost
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'M' THEN
                      MANUL_COST_OVRRD_AMT
                     WHEN ESTMT_COST_IND IS NULL THEN
                      DECODE(CORP_PRMTN_TYPE_CODE,
                             'Annual Agreement',
                             ESTMT_FIXED_COST_AMT +
                             DECODE(REVSD_BPT_COST_AMT,
                                    0,
                                    REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                                    REVSD_BPT_COST_AMT), --BPT Revised Cost
                             ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT)
                   END) AS ESTMT_COST_OVRRD_AMT,
                   (ACTL_VAR_COST_AMT + ACTL_FIXED_COST_AMT) AS COST_BOOK_AMT,
                   DECODE(PRMTN_STTUS_CODE,
                          'Confirmed',
                          --Estimate Total Cost - Actual Cost
                          --Add the logic of Activity Stop date and Pyment allow IND
                          --For Defect 2913 Luke 2010-5-5
                          (CASE
                            WHEN (ACTVY_STOP_DATE IS NULL OR ACTVY_STOP_DATE > SYSDATE OR
                                 NVL(PYMT_ALLWD_STOP_IND, 'N') = 'Y') THEN
                             (CASE
                            WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'E' THEN
                             ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT
                            WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'R' THEN
                             ESTMT_FIXED_COST_AMT +
                             DECODE(REVSD_BPT_COST_AMT,
                                    0,
                                    REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                                    REVSD_BPT_COST_AMT) --BPT Revised Cost
                            WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'M' THEN
                             MANUL_COST_OVRRD_AMT
                            WHEN ESTMT_COST_IND IS NULL THEN
                             DECODE(CORP_PRMTN_TYPE_CODE,
                                    'Annual Agreement',
                                    ESTMT_FIXED_COST_AMT +
                                    DECODE(REVSD_BPT_COST_AMT,
                                           0,
                                           REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                                           REVSD_BPT_COST_AMT), --BPT Revised Cost
                                    ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT)
                          END) - (ACTL_VAR_COST_AMT + ACTL_FIXED_COST_AMT)
                           ELSE 0 END), 0) AS COST_CMMT_AMT,
                   (CASE
                     WHEN (PRMTN_STTUS_CODE IN ('Planned', 'Revised') AND
                          NVL(APPRV_STTUS_CODE, 'Nothing') <> 'Rejected' AND
                          --Add the logic of Activity Stop date and Pyment allow IND
                          --For Defect 2913 Luke 2010-5-5
                          (ACTVY_STOP_DATE IS NULL OR ACTVY_STOP_DATE > SYSDATE OR
                          NVL(PYMT_ALLWD_STOP_IND, 'N') = 'Y')) THEN
                      (CASE
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'E' THEN
                      ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'R' THEN
                      ESTMT_FIXED_COST_AMT +
                      DECODE(REVSD_BPT_COST_AMT,
                             0,
                             REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                             REVSD_BPT_COST_AMT) --BPT Revised Cost
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'M' THEN
                      MANUL_COST_OVRRD_AMT
                     WHEN ESTMT_COST_IND IS NULL THEN
                      DECODE(CORP_PRMTN_TYPE_CODE,
                             'Annual Agreement',
                             ESTMT_FIXED_COST_AMT +
                             DECODE(REVSD_BPT_COST_AMT,
                                    0,
                                    REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                                    REVSD_BPT_COST_AMT), --BPT Revised Cost
                             ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT)
                   END) - (ACTL_VAR_COST_AMT + ACTL_FIXED_COST_AMT) ELSE 0 END) AS COST_PLAN_AMT,
                   (CASE
                     WHEN MTH_START_DATE > TRUNC(SYSDATE, 'MM') AND
                          PRMTN_STTUS_CODE IN ('Planned', 'Confirmed', 'Revised') THEN
                      (CASE
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'E' THEN
                      ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'R' THEN
                      ESTMT_FIXED_COST_AMT +
                      DECODE(REVSD_BPT_COST_AMT,
                             0,
                             REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                             REVSD_BPT_COST_AMT) --BPT Revised Cost
                     WHEN SUBSTR(ESTMT_COST_IND, 1, 1) = 'M' THEN
                      MANUL_COST_OVRRD_AMT
                     WHEN ESTMT_COST_IND IS NULL THEN
                      DECODE(CORP_PRMTN_TYPE_CODE,
                             'Annual Agreement',
                             ESTMT_FIXED_COST_AMT +
                             DECODE(REVSD_BPT_COST_AMT,
                                    0,
                                    REVSD_ESTMT_VAR_COST_AMT, --Ax Revised Estimated Variable Cost
                                    REVSD_BPT_COST_AMT), --BPT Revised Cost
                             ESTMT_FIXED_COST_AMT + ESTMT_VAR_COST_AMT)
                       END)
                   WHEN MTH_START_DATE <= TRUNC(SYSDATE, 'MM') THEN
                      (ACTL_VAR_COST_AMT + ACTL_FIXED_COST_AMT)
                   ELSE 0 END) AS LA_TOT_BOOK_AMT
              FROM (SELECT  ACTVY_MTH_GTIN.ACTVY_SKID,
                           ACTVY_MTH_GTIN.FUND_SKID,
                           ACTVY_MTH_GTIN.PROD_SKID,
                           ACTVY_MTH_GTIN.PRMTN_SKID,
                           ACTVY_MTH_GTIN.MTH_SKID AS DATE_SKID,
                           ACTVY_MTH_GTIN.ACCT_SKID,
                           ACTVY_MTH_GTIN.BUS_UNIT_SKID,
                           ACTVY_MTH_GTIN.FY_DATE_SKID,
                           PRMTN.PRMTN_STTUS_CODE,
                           PRMTN.APPRV_STTUS_CODE,
                           ACTVY.ESTMT_COST_IND,
                           ACTVY.CORP_PRMTN_TYPE_CODE,
                           ACTVY.ACTVY_STOP_DATE,
                           ACTVY.PYMT_ALLWD_STOP_IND,
                           CAL.MTH_START_DATE,
                           ROUND(NVL(DECODE(ACTVY.COST_TYPE_CODE,
                                            '% Fund',
                                            (ACTVY_MTH_GTIN.ESTMT_VAR_COST * -- added by Rita for defect 3105 in R10
                                            ACTVY_MTH_GTIN.ACTVY_GTIN_ESTMT_WGHT_RATE),
                                            DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                                   'Annual Agreement',
                                                   AA.ESTMT_VAR_COST_AMT,
                                                   ESTMT_VAR_COST.ESTMT_VAR_COST_AMT)),
                                     0),
                                 7) AS ESTMT_VAR_COST_AMT,
                           -- Modified by Simon For CR389 in R10 on 2010-3-18
                           ROUND(NVL(DECODE(ACTVY.COST_TYPE_CODE,
                                            -- % Fund
                                            '% Fund',
                                            ACTVY_MTH_GTIN.ESTMT_FIX_COST *
                                            ACTVY_MTH_GTIN.ACTVY_GTIN_ESTMT_WGHT_RATE,
                                            -- Fixed
                                            'Fixed',
                                            ACTVY_MTH_GTIN.ESTMT_FIX_COST *
                                            ACTVY_MTH_GTIN.ACTVY_GTIN_ESTMT_WGHT_RATE,
                                            -- Not % Fund or Fixed
                                            DECODE(DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                                          'Annual Agreement',
                                                          SUM(NVL(AA.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID),
                                                          SUM(NVL(ESTMT_VAR_COST.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID)),
                                                   0,
                                                   ACTVY_MTH_GTIN.ESTMT_FIX_COST *
                                                   BRAND_MTH_RATE,
                                                   ACTVY_MTH_GTIN.ESTMT_FIX_COST *
                                                   NVL(DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                                              'Annual Agreement',
                                                              AA.ESTMT_VAR_COST_AMT,
                                                              ESTMT_VAR_COST.ESTMT_VAR_COST_AMT),
                                                       0) /
                                                   DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                                          'Annual Agreement',
                                                          SUM(NVL(AA.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID),
                                                          SUM(NVL(ESTMT_VAR_COST.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID)))),
                                     0),
                                 7) AS ESTMT_FIXED_COST_AMT,
                           -- Change in R10 for Revised Cost logic
                           ROUND(NVL(DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                            'Annual Agreement',
                                            AA.REVSD_ESTMT_VAR_COST_AMT,
                                            REVSD_VAR_COST.REVSD_ESTMT_VAR_COST_AMT),
                                     0),
                                 7) AS REVSD_ESTMT_VAR_COST_AMT,
                           ROUND(NVL(ESTMT_VAR_COST.REVSD_BPT_COST_AMT, 0), 7) AS REVSD_BPT_COST_AMT,
                           ROUND(NVL((ACTVY_MTH_GTIN.ACTL_VAR_COST *
                                     ACTVY_MTH_GTIN.ACTVY_GTIN_ACTL_WGHT_RATE),
                                     0),
                                 7) AS ACTL_VAR_COST_AMT,
                           ROUND(NVL((ACTVY_MTH_GTIN.ACTL_FIX_COST *
                                     ACTVY_MTH_GTIN.ACTVY_GTIN_ACTL_WGHT_RATE),
                                     0),
                                 7) AS ACTL_FIXED_COST_AMT,
                           ROUND(NVL(DECODE(ACTVY.COST_TYPE_CODE,
                                            '% Fund',
                                            ACTVY_MTH_GTIN.MANUL_COST_OVRRD_AMT *
                                            ACTVY_MTH_GTIN.ACTVY_GTIN_ESTMT_WGHT_RATE,
                                            'Fixed',
                                            ACTVY_MTH_GTIN.MANUL_COST_OVRRD_AMT *
                                            ACTVY_MTH_GTIN.ACTVY_GTIN_ESTMT_WGHT_RATE,
                                            DECODE(DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                                          'Annual Agreement',
                                                          SUM(NVL(AA.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID),
                                                          SUM(NVL(ESTMT_VAR_COST.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID)),
                                                   0,
                                                   ACTVY_MTH_GTIN.MANUL_COST_OVRRD_AMT *
                                                   BRAND_MTH_RATE,
                                                   ACTVY_MTH_GTIN.MANUL_COST_OVRRD_AMT *
                                                   NVL(DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                                              'Annual Agreement',
                                                              AA.ESTMT_VAR_COST_AMT,
                                                              ESTMT_VAR_COST.ESTMT_VAR_COST_AMT),
                                                       0) /
                                                   DECODE(ACTVY.CORP_PRMTN_TYPE_CODE,
                                                          'Annual Agreement',
                                                          SUM(NVL(AA.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID),
                                                          SUM(NVL(ESTMT_VAR_COST.ESTMT_VAR_COST_AMT,
                                                                  0))
                                                          OVER(PARTITION BY
                                                               ACTVY_MTH_GTIN.ACTVY_SKID)))),
                                     0),
                                 7) AS MANUL_COST_OVRRD_AMT
                      FROM OPT_ACTVY_DIM ACTVY,
                           OPT_PRMTN_DIM PRMTN,
                           OPT_CAL_MASTR_DIM CAL,
                           (SELECT ACTVY.ACTVY_SKID,
                                   ACTVY_GTIN_BRAND.ACTVY_ID,
                                   ACTVY.FUND_SKID,
                                   ACTVY.ACCT_PRMTN_SKID AS ACCT_SKID,
                                   ACTVY_GTIN_BRAND.PROD_SKID,
                                   ACTVY_GTIN_BRAND.PROD_ID,
                                   ACTVY_GTIN_BRAND.PRMTN_SKID,
                                   ACTVY.BUS_UNIT_SKID,
                                   ACTVY_GTIN_BRAND.MTH_SKID,
                                   ACTVY_GTIN_BRAND.FY_DATE_SKID,
                                   ACTVY.VAR_COST_ESTMT_AMT AS ESTMT_VAR_COST,
                                   ACTVY.PRDCT_FIXED_COST_AMT AS ESTMT_FIX_COST,
                                   ACTVY.CALC_INDEX_NUM AS ACTL_FIX_COST,
                                   ACTVY.ACTL_VAR_COST_NUM AS ACTL_VAR_COST,
                                   ACTVY.ESTMT_COST_OVRRD_AMT,
                                   ACTVY.MANUL_COST_OVRRD_AMT,
                                   ACTVY_GTIN_BRAND.ACTVY_GTIN_ACTL_WGHT_RATE,
                                   ACTVY_GTIN_BRAND.ACTVY_GTIN_ESTMT_WGHT_RATE,
                                   ACTVY_GTIN_BRAND.BRAND_MTH_RATE
                              FROM OPT_ACTVY_FCT             ACTVY,
                                   OPT_ACTVY_GTIN_BRAND_SFCT ACTVY_GTIN_BRAND,
                                   OPT_ACCT_DIM              ACCT
                             WHERE ACTVY.ACTVY_SKID = ACTVY_GTIN_BRAND.ACTVY_SKID
                               AND ACCT.ACCT_SKID = ACTVY.ACCT_PRMTN_SKID
                               -- Optima11, B018, 9-Oct-2010, Kingham, filter out TSP account
                               AND ACCT.FUND_FRCST_MODEL_DESC not like 'TSP%') ACTVY_MTH_GTIN,
                           --Estamate variable cost aggregated to brand level
                           (SELECT  ESTMT.ACTVY_ID AS ACTVY_ID,
                                   BRAND_HIER.BRAND_ID AS PROD_ID,
                                   ESTMT.DATE_SKID AS DATE_SKID,
                                   ESTMT.BUS_UNIT_SKID AS BUS_UNIT_SKID,
                                   SUM(ESTMT.ESTMT_VAR_COST_AMT) AS ESTMT_VAR_COST_AMT,
                                   SUM(ESTMT.REVSD_BPT_COST_AMT) AS REVSD_BPT_COST_AMT
                              FROM OPT_ACTVY_GTIN_ESTMT_SFCT ESTMT, -- add by rita
                                   OPT_PROD_BRAND_ASSOC_DIM  BRAND_HIER,
                                   CAL_MASTR_DIM             CAL
                             WHERE ESTMT.PROD_ID = BRAND_HIER.PROD_ID
                               AND ESTMT.DATE_SKID = CAL.CAL_MASTR_SKID
                               AND CAL.FISC_YR_SKID = BRAND_HIER.FY_DATE_SKID
                             GROUP BY ESTMT.ACTVY_ID,
                                      BRAND_HIER.BRAND_ID,
                                      ESTMT.DATE_SKID,
                                      ESTMT.BUS_UNIT_SKID) ESTMT_VAR_COST,
                           --Revised variable cost aggregated to brand level
                           (SELECT REVSD.ACTVY_ID AS ACTVY_ID,
                                   BRAND_HIER.BRAND_ID AS PROD_ID,
                                   REVSD.DATE_SKID AS DATE_SKID,
                                   REVSD.BUS_UNIT_SKID AS BUS_UNIT_SKID,
                                   SUM(REVSD.REVSD_ESTMT_VAR_COST_AMT) AS REVSD_ESTMT_VAR_COST_AMT
                              FROM OPT_ACTVY_GTIN_REVSD_SFCT REVSD,
                                   OPT_PROD_BRAND_ASSOC_DIM  BRAND_HIER,
                                   CAL_MASTR_DIM             CAL
                             WHERE REVSD.PROD_ID = BRAND_HIER.PROD_ID
                               AND REVSD.DATE_SKID = CAL.CAL_MASTR_SKID
                               AND CAL.FISC_YR_SKID = BRAND_HIER.FY_DATE_SKID
                             GROUP BY REVSD.ACTVY_ID,
                                      BRAND_HIER.BRAND_ID,
                                      REVSD.DATE_SKID,
                                      REVSD.BUS_UNIT_SKID) REVSD_VAR_COST,
                           --AA Variable Cost aggregated to Brand Level
                           (SELECT  AA.ACTVY_ID AS ACTVY_ID,
                                   BRAND_HIER.BRAND_ID AS PROD_ID,
                                   AA.MTH_SKID AS DATE_SKID,
                                   AA.BUS_UNIT_SKID AS BUS_UNIT_SKID,
                                   SUM(AA.ESTMT_VAR_COST_AMT) AS ESTMT_VAR_COST_AMT,
                                   SUM(AA.REVSD_VAR_ESTMT_COST_AMT) AS REVSD_ESTMT_VAR_COST_AMT
                              FROM OPT_ACTVY_BUOM_GTIN_COST_TFADS AA,
                                   OPT_PROD_BRAND_ASSOC_DIM       BRAND_HIER
                             WHERE AA.BUOM_GTIN_PROD_SKID = BRAND_HIER.PROD_SKID
                               AND BRAND_HIER.FY_DATE_SKID = AA.FY_DATE_SKID
                             GROUP BY AA.ACTVY_ID,
                                      BRAND_HIER.BRAND_ID,
                                      AA.MTH_SKID,
                                      AA.BUS_UNIT_SKID) AA
                     WHERE ACTVY_MTH_GTIN.ACTVY_ID = ESTMT_VAR_COST.ACTVY_ID(+)
                       AND ACTVY_MTH_GTIN.MTH_SKID = ESTMT_VAR_COST.DATE_SKID(+)
                       AND ACTVY_MTH_GTIN.PROD_ID = ESTMT_VAR_COST.PROD_ID(+)
                       AND ACTVY_MTH_GTIN.ACTVY_ID = REVSD_VAR_COST.ACTVY_ID(+)
                       AND ACTVY_MTH_GTIN.MTH_SKID = REVSD_VAR_COST.DATE_SKID(+)
                       AND ACTVY_MTH_GTIN.PROD_ID = REVSD_VAR_COST.PROD_ID(+)
                       AND ACTVY_MTH_GTIN.ACTVY_ID = AA.ACTVY_ID(+)
                       AND ACTVY_MTH_GTIN.MTH_SKID = AA.DATE_SKID(+)
                       AND ACTVY_MTH_GTIN.PROD_ID = AA.PROD_ID(+)
                       AND ACTVY_MTH_GTIN.ACTVY_SKID = ACTVY.ACTVY_SKID
                       AND ACTVY_MTH_GTIN.PRMTN_SKID = PRMTN.PRMTN_SKID
                       AND ACTVY_MTH_GTIN.MTH_SKID = CAL.CAL_MASTR_SKID))
                       );

    该SQL执行计划如下

    SQL> select * from table(dbms_xplan.display);

    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------------------------------------------------------

    Plan hash value: 2005223222

    --------------------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation                                       | Name                           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    --------------------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                                |                                |     1 |   249 |  3855  (39)| 00:00:27 |       |       |
    |   1 |  VIEW                                           |                                |     1 |   249 |  3855  (39)| 00:00:27 |       |       |
    |   2 |   WINDOW BUFFER                                 |                                |     1 |   308 |  3855  (39)| 00:00:27 |       |       |
    |   3 |    VIEW                                         |                                |     1 |   308 |  3855  (39)| 00:00:27 |       |       |
    |   4 |     WINDOW SORT                                 |                                |     1 |   376 |  3855  (39)| 00:00:27 |       |       |
    |   5 |      NESTED LOOPS                               |                                |       |    |       |          |       |       |
    |   6 |       NESTED LOOPS                              |                                |     1 |   376 |  3854  (39)| 00:00:27 |       |       |
    |   7 |        NESTED LOOPS                             |                                |     1 |   351 |  3852  (39)| 00:00:27 |       |       |
    |*  8 |         HASH JOIN OUTER                         |                                |     1 |   338 |  3851  (39)| 00:00:27 |       |       |
    |*  9 |          HASH JOIN OUTER                        |                                |     1 |   281 |  3536  (41)| 00:00:25 |       |       |
    |* 10 |           HASH JOIN OUTER                       |                                |     1 |   237 |  3223  (43)| 00:00:23 |       |       |
    |* 11 |            HASH JOIN                            |                                |     1 |   180 |  3218  (43)| 00:00:23 |       |       |
    |  12 |             NESTED LOOPS                        |                                |       |    |       |          |       |       |
    |  13 |              NESTED LOOPS                       |                                |     1 |   116 |   535   (7)| 00:00:04 |       |       |
    |* 14 |               HASH JOIN                         |                                |     1 |    65 |   533   (7)| 00:00:04 |       |       |
    |  15 |                PARTITION LIST ALL               |                                |     1 |    26 |   315   (6)| 00:00:03 |     1 |    17 |
    |* 16 |                 TABLE ACCESS FULL               | OPT_ACCT_DIM                   |     1 |    26 |   315   (6)| 00:00:03 |     1 |    17 |
    |  17 |                PARTITION LIST ALL               |                                |   114K|  4363K|   216   (7)| 00:00:02 |     1 |    17 |
    |  18 |                 TABLE ACCESS FULL               | OPT_ACTVY_FCT                  |   114K|  4363K|   216   (7)| 00:00:02 |     1 |    17 |
    |* 19 |               INDEX RANGE SCAN                  | OPT_ACTVY_DIM_PK               |     1 |    |     1   (0)| 00:00:01 |  |       |
    |  20 |              TABLE ACCESS BY GLOBAL INDEX ROWID | OPT_ACTVY_DIM                  |     1 |    51 |     2   (0)| 00:00:01 | ROWID | ROWID |
    |  21 |             PARTITION LIST ALL                  |                                |    19M|  1212M|  2423  (45)| 00:00:17 |     1 |    17 |
    |  22 |              TABLE ACCESS FULL                  | OPT_ACTVY_GTIN_BRAND_SFCT      |    19M|  1212M|  2423  (45)| 00:00:17 |     1 |    17 |
    |  23 |            VIEW                                 |                                |     1 |    57 |     5  (20)| 00:00:01 |       |       |
    |  24 |             HASH GROUP BY                       |                                |     1 |   108 |     5  (20)| 00:00:01 |       |       |
    |  25 |              NESTED LOOPS                       |                                |       |    |       |          |       |       |
    |  26 |               NESTED LOOPS                      |                                |     1 |   108 |     4   (0)| 00:00:01 |       |       |
    |  27 |                TABLE ACCESS FULL                | OPT_ACTVY_BUOM_GTIN_COST_TFADS |     1 |    87 |     2   (0)| 00:00:01 |       |       |
    |* 28 |                INDEX RANGE SCAN                 | OPT_PROD_BRAND_ASSOC_DIM_PK    |     1 |    |     2   (0)| 00:00:01 |  |       |
    |  29 |               TABLE ACCESS BY GLOBAL INDEX ROWID| OPT_PROD_BRAND_ASSOC_DIM       |     1 |    21 |     2   (0)| 00:00:01 | ROWID | ROWID |
    |  30 |           VIEW                                  |                                |   718 | 31592 |   313  (17)| 00:00:03 |       |       |
    |  31 |            HASH GROUP BY                        |                                |   718 | 51696 |   313  (17)| 00:00:03 |       |       |
    |* 32 |             HASH JOIN                           |                                |   718 | 51696 |   311  (17)| 00:00:03 |       |       |
    |* 33 |              HASH JOIN                          |                                |   872 | 40112 |   211   (8)| 00:00:02 |       |       |
    |  34 |               PARTITION LIST ALL                |                                |   872 | 31392 |     3   (0)| 00:00:01 |     1 |    17 |
    |  35 |                TABLE ACCESS FULL                | OPT_ACTVY_GTIN_REVSD_SFCT      |   872 | 31392 |     3   (0)| 00:00:01 |     1 |    17 |
    |  36 |               TABLE ACCESS FULL                 | OPT_CAL_MASTR_DIM              | 36826 |   359K|   207   (8)| 00:00:02 |       |       |
    |  37 |              PARTITION LIST ALL                 |                                |   671K|    16M|    91  (28)| 00:00:01 |     1 |    17 |
    |  38 |               TABLE ACCESS FULL                 | OPT_PROD_BRAND_ASSOC_DIM       |   671K|    16M|    91  (28)| 00:00:01 |     1 |    17 |
    |  39 |          VIEW                                   |                                |  6174 |   343K|   315  (17)| 00:00:03 |       |       |
    |  40 |           HASH GROUP BY                         |                                |  6174 |   446K|   315  (17)| 00:00:03 |       |       |
    |* 41 |            HASH JOIN                            |                                |  6174 |   446K|   313  (17)| 00:00:03 |       |       |
    |* 42 |             HASH JOIN                           |                                |  8998 |   421K|   213   (8)| 00:00:02 |       |       |
    |  43 |              PARTITION LIST ALL                 |                                |  8998 |   333K|     4   (0)| 00:00:01 |     1 |    17 |
    |  44 |               TABLE ACCESS FULL                 | OPT_ACTVY_GTIN_ESTMT_SFCT      |  8998 |   333K|     4   (0)| 00:00:01 |     1 |    17 |
    |  45 |              TABLE ACCESS FULL                  | OPT_CAL_MASTR_DIM              | 36826 |   359K|   207   (8)| 00:00:02 |       |       |
    |  46 |             PARTITION LIST ALL                  |                                |   671K|    16M|    91  (28)| 00:00:01 |     1 |    17 |
    |  47 |              TABLE ACCESS FULL                  | OPT_PROD_BRAND_ASSOC_DIM       |   671K|    16M|    91  (28)| 00:00:01 |     1 |    17 |
    |  48 |         TABLE ACCESS BY INDEX ROWID             | OPT_CAL_MASTR_DIM              |     1 |    13 |     1   (0)| 00:00:01 |       |       |
    |* 49 |          INDEX UNIQUE SCAN                      | OPT_CAL_MASTR_DIM_PK           |     1 |    |     0   (0)| 00:00:01 |  |       |
    |* 50 |        INDEX RANGE SCAN                         | OPT_PRMTN_DIM_PK               |     1 |    |     1   (0)| 00:00:01 |  |       |
    |  51 |       TABLE ACCESS BY GLOBAL INDEX ROWID        | OPT_PRMTN_DIM                  |     1 |    25 |     2   (0)| 00:00:01 | ROWID | ROWID |
    --------------------------------------------------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       8 - access("ACTVY_GTIN_BRAND"."ACTVY_ID"="ESTMT_VAR_COST"."ACTVY_ID"(+) AND
                  "ACTVY_GTIN_BRAND"."MTH_SKID"="ESTMT_VAR_COST"."DATE_SKID"(+) AND "ACTVY_GTIN_BRAND"."PROD_ID"="ESTMT_VAR_COST"."PROD_ID"(+))
       9 - access("ACTVY_GTIN_BRAND"."ACTVY_ID"="REVSD_VAR_COST"."ACTVY_ID"(+) AND
                  "ACTVY_GTIN_BRAND"."MTH_SKID"="REVSD_VAR_COST"."DATE_SKID"(+) AND "ACTVY_GTIN_BRAND"."PROD_ID"="REVSD_VAR_COST"."PROD_ID"(+))
      10 - access("ACTVY_GTIN_BRAND"."ACTVY_ID"="AA"."ACTVY_ID"(+) AND "ACTVY_GTIN_BRAND"."MTH_SKID"="AA"."DATE_SKID"(+) AND
                  "ACTVY_GTIN_BRAND"."PROD_ID"="AA"."PROD_ID"(+))
      11 - access("ACTVY"."ACTVY_SKID"="ACTVY_GTIN_BRAND"."ACTVY_SKID")
      14 - access("ACCT"."ACCT_SKID"="ACTVY"."ACCT_PRMTN_SKID")
      16 - filter("ACCT"."FUND_FRCST_MODEL_DESC" NOT LIKE 'TSP%')
      19 - access("ACTVY"."ACTVY_SKID"="ACTVY"."ACTVY_SKID")
      28 - access("AA"."BUOM_GTIN_PROD_SKID"="BRAND_HIER"."PROD_SKID" AND "BRAND_HIER"."FY_DATE_SKID"="AA"."FY_DATE_SKID")
      32 - access("REVSD"."PROD_ID"="BRAND_HIER"."PROD_ID" AND "CAL"."FISC_YR_SKID"="BRAND_HIER"."FY_DATE_SKID")
      33 - access("REVSD"."DATE_SKID"="CAL"."CAL_MASTR_SKID")
      41 - access("ESTMT"."PROD_ID"="BRAND_HIER"."PROD_ID" AND "CAL"."FISC_YR_SKID"="BRAND_HIER"."FY_DATE_SKID")
      42 - access("ESTMT"."DATE_SKID"="CAL"."CAL_MASTR_SKID")
      49 - access("ACTVY_GTIN_BRAND"."MTH_SKID"="CAL"."CAL_MASTR_SKID")
      50 - access("ACTVY_GTIN_BRAND"."PRMTN_SKID"="PRMTN"."PRMTN_SKID")

    79 rows selected.

    Elapsed: 00:00:03.45

    由于这个SQL语句的执行计划太复杂,所以这里暂不关注执行计划,我们来监控该SQL语句的等待事件

    我手工运行该SQL,监控等待事件,发现在等待 direct path write temp

    SQL> select username,inst_id,sid,serial#,event,p1,p2,p3,sql_id,sql_child_number
      2  from gv$session where username='ADWU_OPTIMA_LA11' and osuser='luobi';

    USERNAME                INST_ID        SID    SERIAL# EVENT                                  P1         P2         P3 SQL_ID        SQL_CHILD_NUMBER
    -------------------- ---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ------------- ----------------
    ADWU_OPTIMA_LA11              2       4754      10050 direct path write temp              20025     857328          7 6qsuc8mafy20m                0

    SQL> /

    USERNAME                INST_ID        SID    SERIAL# EVENT                                  P1         P2         P3 SQL_ID        SQL_CHILD_NUMBER
    -------------------- ---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ------------- ----------------
    ADWU_OPTIMA_LA11              2       4754      10050 direct path write temp              20025     406768          7 6qsuc8mafy20m                0
    SQL> /

    USERNAME                INST_ID        SID    SERIAL# EVENT                                  P1         P2         P3 SQL_ID        SQL_CHILD_NUMBER
    -------------------- ---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ------------- ----------------
    ADWU_OPTIMA_LA11              2       4754      10050 direct path write temp              20007    2849264          7 6qsuc8mafy20m                0

    SQL> /

    USERNAME                INST_ID        SID    SERIAL# EVENT                                  P1         P2         P3 SQL_ID        SQL_CHILD_NUMBER
    -------------------- ---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ------------- ----------------
    ADWU_OPTIMA_LA11              2       4754      10050 direct path write temp              20007     115341          7 6qsuc8mafy20m                0

    SQL> /

    USERNAME                INST_ID        SID    SERIAL# EVENT                                  P1         P2         P3 SQL_ID        SQL_CHILD_NUMBER
    -------------------- ---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ------------- ----------------
    ADWU_OPTIMA_LA11              2       4754      10050 direct path write temp              20007      81029          7 6qsuc8mafy20m                0

    我又查询这个SESSION到底是HASH JOIN 暂用了 temp tablespace 还是 sort 占用了temp tablespace

    SQL> select a.username,a.inst_id, a.sid, a.serial#, a.machine,a.sql_id,b.tablespace, b.blocks*
      2  (select value from v$parameter where name='db_block_size')/1024/1024 "Size(M)",b.segtype
      3  from gv$session a, gv$tempseg_usage b where a.inst_id=b.inst_id and a.saddr = b.session_addr
      4  and a.inst_id=2 and a.sid=4754
      5  ;

    USERNAME                INST_ID        SID    SERIAL# MACHINE              SQL_ID        TABLESPACE                         Size(M) SEGTYPE
    -------------------- ---------- ---------- ---------- -------------------- ------------- ------------------------------- ---------- ---------
    ADWU_OPTIMA_LA11              2       4754      10050 ASIAPACIFIC\BLUO7    6qsuc8mafy20m TEMP                                     1 DATA
    ADWU_OPTIMA_LA11              2       4754      10050 ASIAPACIFIC\BLUO7    6qsuc8mafy20m TEMP                                     1 LOB_DATA
    ADWU_OPTIMA_LA11              2       4754      10050 ASIAPACIFIC\BLUO7    6qsuc8mafy20m TEMP                                     1 INDEX
    ADWU_OPTIMA_LA11              2       4754      10050 ASIAPACIFIC\BLUO7    6qsuc8mafy20m TEMP                                     1 LOB_DATA
    ADWU_OPTIMA_LA11              2       4754      10050 ASIAPACIFIC\BLUO7    6qsuc8mafy20m TEMP                                  3304 HASH

    那么根据查询,这个会话在等磁盘HASH操作,ETL开发人员跟我报告的时候,我用TOAD监控了一下,
    那个job确实在等待 direct patch write temp 操作。

    在OLAP中,由于数据量巨大,业务逻辑复杂,有时候确实无法避免磁盘HASH,磁盘SORT等操作

    大家请注意观察p3, p3=7 也就是说一次 temp 写入只能写入7个block

    好的,那么我现在kill 这个SESSION,我设置workarea 手工管理

    SQL> alter session set workarea_size_policy = manual;

    Session altered.

    SQL> alter session set hash_area_size = 2100000000;

    Session altered.

    SQL> alter session set sort_area_size = 2100000000;

    Session altered.

    Oracle有个限制,每个进程分配的最大内存不能够操作2G 。在workarea自动管理中,每个进程的work area不能超过1G

    所以当你尝试分配2G的hash_area给 这个进程,会报错

    SQL> alter session set hash_area_size = 2147483648;
    alter session set hash_area_size = 2147483648
                                       *
    ERROR at line 1:
    ORA-02017: integer value required


    SQL> alter session set hash_area_size = 2147483647;

    Session altered.

    好了 关于此话题,就到此结束,本人博客前面提到过这个问题,我们再来运行一下这个SQL,并且监控等待事件

    SQL> select username,inst_id,sid,serial#,event,p1,p2,p3,sql_id,sql_child_number
      2  from gv$session where username='ADWU_OPTIMA_LA11' and osuser='luobi';

    USERNAME                INST_ID        SID    SERIAL# EVENT                                  P1         P2         P3 SQL_ID        SQL_CHILD_NUMBER
    -------------------- ---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ------------- ----------------
    ADWU_OPTIMA_LA11              2       4885      11759 direct path write temp              20012      71053         64 6qsuc8mafy20m                1

    请注意观察 p3 ,当设置 workarea 手工管理的时候,一次能写入64个block,相比以前的 7个block来说写入速度加快9倍

    那么现在大家也该明白了,这个SQL的主要性能问题就是在于在 在workarea 自动管理模式下磁盘HASH 的时候一次只能写入7个block
    而设置workarea 手工管理,可以让磁盘HASH 一次写入64个block。我现在还没搞明白为什么一次 磁盘HASH只能写入 7个block
    我不是SYSDBA,不能做详细测试,关于这个问题就暂时到此为止

    其实这个SQL不光有 磁盘hash 这个问题存在,它的执行计划也有问题的

    大家请看执行计划中ID=13 到 ID=19 的步骤
     
    |  13 |              NESTED LOOPS                       |                                |     1 |   116 |   535   (7)| 00:00:04 |       |       |
    |* 14 |               HASH JOIN                         |                                |     1 |    65 |   533   (7)| 00:00:04 |       |       |
    |  15 |                PARTITION LIST ALL               |                                |     1 |    26 |   315   (6)| 00:00:03 |     1 |    17 |
    |* 16 |                 TABLE ACCESS FULL               | OPT_ACCT_DIM                   |     1 |    26 |   315   (6)| 00:00:03 |     1 |    17 |
    |  17 |                PARTITION LIST ALL               |                                |   114K|  4363K|   216   (7)| 00:00:02 |     1 |    17 |
    |  18 |                 TABLE ACCESS FULL               | OPT_ACTVY_FCT                  |   114K|  4363K|   216   (7)| 00:00:02 |     1 |    17 |
    |* 19 |               INDEX RANGE SCAN                  | OPT_ACTVY_DIM_PK               |     1 |    |     1   (0)| 00:00:01 |  |       |

    首先 是 OPT_ACCT_DIM 与  OPT_ACTVY_FCT HASH 连接,然后 作为一个嵌套循环的驱动行源,大家请看
    这个HASH 连接, CBO认为它只返回1行数据, 为什么返回一行数据呢,原因在于 Oracle认为 扫描 OPT_ACCT_DIM只会返回1行数据
    那么我来查询一下 扫描 OPT_ACCT_DIM 要返回多少数据

    SQL> select count(*) from OPT_ACCT_DIM ;

      COUNT(*)
    ----------
         94398

    Elapsed: 00:00:01.37
    SQL> select count(*) from OPT_ACTVY_FCT;

      COUNT(*)
    ----------
        114066

    很明显了,OPT_ACCT_DIM表的统计信息没收集,而OPT_ACTVY_FCT的统计信息是对的,于是我马上对OPT_ACCT_DIM收集统计信息

    SQL> BEGIN
      2  DBMS_STATS.GATHER_TABLE_STATS(ownname => 'adwu_optima_la11',
      3  tabname => 'OPT_ACCT_DIM',
      4  estimate_percent => 30,
      5  method_opt=>'for all columns size auto',
      6  degree => DBMS_STATS.AUTO_DEGREE,
      7  cascade=>TRUE
      8  );
      9  END;
     10  /

    PL/SQL procedure successfully completed.


    现在来看一下执行计划

    SQL> select * from table(dbms_xplan.display);

    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------------------------------------------------------------

    Plan hash value: 183294992

    ---------------------------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation                                      | Name                           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
    ---------------------------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                               |                                |    19M|  4718M|       |   848K  (2)| 01:37:06 |       |       |
    |   1 |  VIEW                                          |                                |    19M|  4718M|       |   848K  (2)| 01:37:06 |       |       |
    |   2 |   WINDOW BUFFER                                |                                |    19M|  5836M|       |   848K  (2)| 01:37:06 |       |       |
    |   3 |    VIEW                                        |                                |    19M|  5836M|       |   848K  (2)| 01:37:06 |       |       |
    |   4 |     WINDOW SORT                                |                                |    19M|  7125M|  7392M|   848K  (2)| 01:37:06 |       |       |
    |*  5 |      HASH JOIN                                 |                                |    19M|  7125M|       | 28490  (12)| 00:03:16 |       |       |
    |   6 |       PARTITION LIST ALL                       |                                | 37880 |   924K|       |   407   (3)| 00:00:03 |     1 |    17 |
    |   7 |        TABLE ACCESS FULL                       | OPT_PRMTN_DIM                  | 37880 |   924K|       |   407   (3)| 00:00:03 |     1 |    17 |
    |*  8 |       HASH JOIN                                |                                |    19M|  6651M|       | 27822  (11)| 00:03:12 |       |       |
    |   9 |        TABLE ACCESS FULL                       | OPT_CAL_MASTR_DIM              | 36826 |   467K|       |   200   (4)| 00:00:02 |       |       |
    |* 10 |        HASH JOIN RIGHT OUTER                   |                                |    19M|  6405M|       | 27362  (10)| 00:03:08 |       |       |
    |  11 |         VIEW                                   |                                |  6174 |   343K|       |   315  (17)| 00:00:03 |       |       |
    |  12 |          HASH GROUP BY                         |                                |  6174 |   446K|       |   315  (17)| 00:00:03 |       |       |
    |* 13 |           HASH JOIN                            |                                |  6174 |   446K|       |   313  (17)| 00:00:03 |       |       |
    |* 14 |            HASH JOIN                           |                                |  8998 |   421K|       |   213   (8)| 00:00:02 |       |       |
    |  15 |             PARTITION LIST ALL                 |                                |  8998 |   333K|       |     4   (0)| 00:00:01 |     1 |    17 |
    |  16 |              TABLE ACCESS FULL                 | OPT_ACTVY_GTIN_ESTMT_SFCT      |  8998 |   333K|       |     4   (0)| 00:00:01 |     1 |    17 |
    |  17 |             TABLE ACCESS FULL                  | OPT_CAL_MASTR_DIM              | 36826 |   359K|       |   207   (8)| 00:00:02 |       |       |
    |  18 |            PARTITION LIST ALL                  |                                |   671K|    16M|       |    91  (28)| 00:00:01 |     1 |    17 |
    |  19 |             TABLE ACCESS FULL                  | OPT_PROD_BRAND_ASSOC_DIM       |   671K|    16M|       |    91  (28)| 00:00:01 |     1 |    17 |
    |* 20 |         HASH JOIN RIGHT OUTER                  |                                |    19M|  5325M|       | 26787   (9)| 00:03:05 |       |       |
    |  21 |          VIEW                                  |                                |   718 | 31592 |       |   313  (17)| 00:00:03 |       |       |
    |  22 |           HASH GROUP BY                        |                                |   718 | 51696 |       |   313  (17)| 00:00:03 |       |       |
    |* 23 |            HASH JOIN                           |                                |   718 | 51696 |       |   311  (17)| 00:00:03 |       |       |
    |* 24 |             HASH JOIN                          |                                |   872 | 40112 |       |   211   (8)| 00:00:02 |       |       |
    |  25 |              PARTITION LIST ALL                |                                |   872 | 31392 |       |     3   (0)| 00:00:01 |     1 |    17 |
    |  26 |               TABLE ACCESS FULL                | OPT_ACTVY_GTIN_REVSD_SFCT      |   872 | 31392 |       |     3   (0)| 00:00:01 |     1 |    17 |
    |  27 |              TABLE ACCESS FULL                 | OPT_CAL_MASTR_DIM              | 36826 |   359K|       |   207   (8)| 00:00:02 |       |       |
    |  28 |             PARTITION LIST ALL                 |                                |   671K|    16M|       |    91  (28)| 00:00:01 |     1 |    17 |
    |  29 |              TABLE ACCESS FULL                 | OPT_PROD_BRAND_ASSOC_DIM       |   671K|    16M|       |    91  (28)| 00:00:01 |     1 |    17 |
    |* 30 |          HASH JOIN RIGHT OUTER                 |                                |    19M|  4491M|       | 26215   (8)| 00:03:01 |       |       |
    |  31 |           VIEW                                 |                                |     1 |    57 |       |     5  (20)| 00:00:01 |       |       |
    |  32 |            HASH GROUP BY                       |                                |     1 |   108 |       |     5  (20)| 00:00:01 |       |       |
    |  33 |             NESTED LOOPS                       |                                |       |    |  |            |          |       |       |
    |  34 |              NESTED LOOPS                      |                                |     1 |   108 |       |     4   (0)| 00:00:01 |       |       |
    |  35 |               TABLE ACCESS FULL                | OPT_ACTVY_BUOM_GTIN_COST_TFADS |     1 |    87 |       |     2   (0)| 00:00:01 |       |       |
    |* 36 |               INDEX RANGE SCAN                 | OPT_PROD_BRAND_ASSOC_DIM_PK    |     1 |    |  |     2   (0)| 00:00:01 |       |       |
    |  37 |              TABLE ACCESS BY GLOBAL INDEX ROWID| OPT_PROD_BRAND_ASSOC_DIM       |     1 |    21 |       |     2   (0)| 00:00:01 | ROWID | ROWID |
    |* 38 |           HASH JOIN                            |                                |    19M|  3411M|    14M| 25950   (7)| 00:02:59 |       |       |
    |* 39 |            HASH JOIN                           |                                |   114K|    12M|  7104K|  1302   (6)| 00:00:09 |       |       |
    |  40 |             PARTITION LIST ALL                 |                                |   115K|  5745K|       |   394   (7)| 00:00:03 |     1 |    17 |
    |  41 |              TABLE ACCESS FULL                 | OPT_ACTVY_DIM                  |   115K|  5745K|       |   394   (7)| 00:00:03 |     1 |    17 |
    |* 42 |             HASH JOIN                          |                                |   114K|  7273K|  3520K|   672   (6)| 00:00:05 |       |       |
    |  43 |              PARTITION LIST ALL                |                                | 94478 |  2398K|       |   315   (6)| 00:00:03 |     1 |    17 |
    |* 44 |               TABLE ACCESS FULL                | OPT_ACCT_DIM                   | 94478 |  2398K|       |   315   (6)| 00:00:03 |     1 |    17 |
    |  45 |              PARTITION LIST ALL                |                                |   114K|  4363K|       |   216   (7)| 00:00:02 |     1 |    17 |
    |  46 |               TABLE ACCESS FULL                | OPT_ACTVY_FCT                  |   114K|  4363K|       |   216   (7)| 00:00:02 |     1 |    17 |
    |  47 |            PARTITION LIST ALL                  |                                |    19M|  1212M|       |  2423  (45)| 00:00:17 |     1 |    17 |
    |  48 |             TABLE ACCESS FULL                  | OPT_ACTVY_GTIN_BRAND_SFCT      |    19M|  1212M|       |  2423  (45)| 00:00:17 |     1 |    17 |
    ---------------------------------------------------------------------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       5 - access("ACTVY_GTIN_BRAND"."PRMTN_SKID"="PRMTN"."PRMTN_SKID")
       8 - access("ACTVY_GTIN_BRAND"."MTH_SKID"="CAL"."CAL_MASTR_SKID")
      10 - access("ACTVY_GTIN_BRAND"."ACTVY_ID"="ESTMT_VAR_COST"."ACTVY_ID"(+) AND "ACTVY_GTIN_BRAND"."MTH_SKID"="ESTMT_VAR_COST"."DATE_SKID"(+) AND
                  "ACTVY_GTIN_BRAND"."PROD_ID"="ESTMT_VAR_COST"."PROD_ID"(+))
      13 - access("ESTMT"."PROD_ID"="BRAND_HIER"."PROD_ID" AND "CAL"."FISC_YR_SKID"="BRAND_HIER"."FY_DATE_SKID")
      14 - access("ESTMT"."DATE_SKID"="CAL"."CAL_MASTR_SKID")
      20 - access("ACTVY_GTIN_BRAND"."ACTVY_ID"="REVSD_VAR_COST"."ACTVY_ID"(+) AND "ACTVY_GTIN_BRAND"."MTH_SKID"="REVSD_VAR_COST"."DATE_SKID"(+) AND
                  "ACTVY_GTIN_BRAND"."PROD_ID"="REVSD_VAR_COST"."PROD_ID"(+))
      23 - access("REVSD"."PROD_ID"="BRAND_HIER"."PROD_ID" AND "CAL"."FISC_YR_SKID"="BRAND_HIER"."FY_DATE_SKID")
      24 - access("REVSD"."DATE_SKID"="CAL"."CAL_MASTR_SKID")
      30 - access("ACTVY_GTIN_BRAND"."ACTVY_ID"="AA"."ACTVY_ID"(+) AND "ACTVY_GTIN_BRAND"."MTH_SKID"="AA"."DATE_SKID"(+) AND
                  "ACTVY_GTIN_BRAND"."PROD_ID"="AA"."PROD_ID"(+))
      36 - access("AA"."BUOM_GTIN_PROD_SKID"="BRAND_HIER"."PROD_SKID" AND "BRAND_HIER"."FY_DATE_SKID"="AA"."FY_DATE_SKID")
      38 - access("ACTVY"."ACTVY_SKID"="ACTVY_GTIN_BRAND"."ACTVY_SKID")
      39 - access("ACTVY"."ACTVY_SKID"="ACTVY"."ACTVY_SKID")
      42 - access("ACCT"."ACCT_SKID"="ACTVY"."ACCT_PRMTN_SKID")
      44 - filter("ACCT"."FUND_FRCST_MODEL_DESC" NOT LIKE 'TSP%')

    76 rows selected.

    Elapsed: 00:00:04.28


    我发现绝大多数表与表之间的连接都走了全表扫描以及HASH 连接,但是请看Id=35这一步
    全表扫描 居然CBO也认为只返回 一行

    |  34 |              NESTED LOOPS                      |                                |     1 |   108 |       |     4   (0)| 00:00:01 |       |       |
    |  35 |               TABLE ACCESS FULL                | OPT_ACTVY_BUOM_GTIN_COST_TFADS |     1 |    87 |       |     2   (0)| 00:00:01 |       |       |
    |* 36 |               INDEX RANGE SCAN                 | OPT_PROD_BRAND_ASSOC_DIM_PK    |     1 |    |  |     2   (0)| 00:00:01 |       |       |
    |  37 |              TABLE ACCESS BY GLOBAL INDEX ROWID| OPT_PROD_BRAND_ASSOC_DIM       |     1 |    21 |       |     2   (0)| 00:00:01 | ROWID | ROWID |

    好的, 我检查一下 OPT_ACTVY_BUOM_GTIN_COST_TFADS  统计信息是否过期

    SQL> exec dbms_stats.flush_database_monitoring_info;

    PL/SQL procedure successfully completed.

    SQL> select owner || '.' || table_name name , object_type,stale_stats,last_analyzed from dba_tab_statistics
      2  where owner=upper('adwu_optima_la11') and table_name='OPT_ACTVY_BUOM_GTIN_COST_TFADS';

    NAME                                               OBJECT_TYPE          STALE_STATS          LAST_ANALYZED
    -------------------------------------------------- -------------------- -------------------- ------------------
    ADWU_OPTIMA_LA11.OPT_ACTVY_BUOM_GTIN_COST_TFADS    TABLE                NO                   03-DEC-10

    统计信息是没过期的

    好的,我现在再RUN一次这个SQL

    先跑的是 没有并行的SQL 手动设置 workarea
    后炮的是 自动workarea


    经过测试 手工设置workarea的SQL 只需要50分钟左右就能完成,而自动的workarea管理的SQL 还在等待direct path write temp


    6889440 rows selected.

    Elapsed: 00:56:36.08

    到此,这个400行的SQL优化完毕。

    总结: 对于有大量磁盘HASH,磁盘SORT的操作,我们可以设置workarea 手工管理,从而突破workarea 不能超过1G的限制,另外也
    让磁盘HASH 能一次性写入60个block以上,而非一次性写入7个。还有就是统计信息,统计信息对于Oracle太重要了统计信息没收集
    好,会死人滴。

    这里我有两个疑问:

    1.hash_area_size和sort_area_size:两个参数,我首先查看了reference,最大值为os dependent,可见,官方并未明确规定这个参数的最大值,但我在我的本子上测试,确实象我这个朋友所说,不能超过2G,但我的本子memory是2G,是否和这个有关呢?我认为在workarea_size_policy=manual下,可以设置更大些,但会受到物理内存或OS的限制;workarea_size_policy=auto下,这两个值的设置不会再起作用,系统会算出这两个参数的默认值,或者通过修改某些隐含参数进行设定。

    2.关于在workarea_size_policy=auto下,temp IO的大小会受到隐含参数_max_temp_IO和_min_temp_IO的限制;而在workarea_size_policy=manul下,temp IO也会受某些隐含参数的限制,只是,我没有发现这些参数。

    Oracle & Mysql & Postgresql & MSSQL 调优 & 优化
    ----------------------------------------------------------
    《高性能SQL调优精要与案例解析》
    blog1:http://www.cnblogs.com/lhdz_bj
    blog2:http://blog.itpub.net/8484829
    blog3:http://blog.csdn.net/tuning_optmization
  • 相关阅读:
    soj#547 bzoj5046 分糖果游戏
    soj#551 loj#2833 帐篷
    nb哒LCA
    soj#532 set p3175
    p4042 [AHOI2014/JSOI2014]骑士游戏
    p1501 [国家集训队]Tree II
    908G New Year and Original Order
    908D New Year and Arbitrary Arrangement
    EZOJ #258
    EZOJ #257
  • 原文地址:https://www.cnblogs.com/lhdz_bj/p/2011240.html
Copyright © 2020-2023  润新知