1. 程式人生 > >一個跑不出結果的檢視的優化

一個跑不出結果的檢視的優化

作為銀行乙方開發DBA,職責之一就是每個月都給銀行各個系統出一份效能優化報告

連續給某個系統優化了好幾條坑爹的大SQL之後,介面人今天找到我說 有一個檢視從建立開始

和這個檢視相關的SQL從來沒有跑出來過。最長的一次跑了24小時沒出結果。檢視單跑也是2個小時跑不出來

使用者很是抱怨,甚至現在都沒有人願意去點這個頁面了,基本要放棄了,問我能不能拯救一下

檢視原始碼SQL如下:

CREATE OR REPLACE VIEW VW_RPT_ AS
select ct 檢查型別
 ,cc          錯誤型別
      ,org_l1            一級行編碼
      ,org_l1_desc       一級行說明
      ,org_l2            二級行編碼
      ,org_l2_desc        二級行說明
      ,leaf_code   責任中心編碼
      ,leaf_desc 責任中心說明
      ,occur_bal         發生額
      from
(With val_yxtd As
  (  select /*+ parallel(aa,4) +*/ *
  from smg_wrk_relation aa
  where exists
  (select 1 from wrk_acct_mgr a
  inner join instrument_table b
  on  substr(a.acct_no,1,16) = substr(b.cust_acct_no,1,16)
  where  a.mgr_code = aa.orgin_code1
  and a.org_l2 = aa.orgin_code2
  )
  and  aa.relation_type = 'cc_mgr'),
ledger_occur As
 (select nvl(l.opt_txt10,cost_center) cost_center,occur_bal from (
 Select cost_center
        ,Sum(occur_bal) occur_bal
  From   ledger_stat
  Where  src_id = 'SG'
  Group  By cost_center) m
  left join smg_def_leves l --表中維護總賬成本落在金融工具表中經營主體 對應opt_txt10欄位維護
on l.leaf_code=m.cost_center
and l.field_id=8 and l.opt_txt10 is not null),--459089.36,
org_l2 As
 (Select Distinct level_01_code org_l1
                 ,level_01_desc org_l1_desc
                 ,level_02_code org_l2
                 ,level_02_desc org_l2_desc
  From   dim_tree_3)
Select '責任中心為營銷團隊但無有效賬戶' ct
      ,'沒有維護營銷團隊與客戶經理關係的資料' cc
      ,e.org_l1
      ,e.org_l1_desc
      ,e.org_l2
      ,e.org_l2_desc
      ,c.leaf_code
      ,c.leaf_desc
      ,nvl(b.occur_bal,
           0) occur_bal
From   vw_cost_center c
      ,org_l2         e
      ,ledger_occur   b
Where  c.opt_txt1 = 'MK'
And    c.opt_txt20 = e.org_l2
And    c.leaf_code = b.cost_center(+)
And    Not Exists (Select 1
        From   smg_wrk_relation f
        Where  c.leaf_code = f.relation_code
        And    f.relation_type = 'cc_mgr')
Union All
Select '責任中心為營銷團隊但無有效賬戶' ct
      ,'維護營銷團隊與客戶經理關係,但仍不存在有效賬戶的資料' cc
      ,e.org_l1
      ,e.org_l1_desc
      ,e.org_l2
      ,e.org_l2_desc
      ,c.leaf_code
      ,c.leaf_desc
      ,nvl(b.occur_bal,
            0) occur_bal
From   vw_cost_center c
      ,org_l2         e
      ,ledger_occur   b
Where  c.opt_txt1 = 'MK'
 And c.opt_txt20 = e.org_l2
 And c.leaf_code = b.cost_center(+)
 And Exists (Select 1
  From   smg_wrk_relation f
  Where  c.leaf_code = f.relation_code
  And    f.relation_type = 'cc_mgr')
 And Not Exists (Select 1
  From   val_yxtd f
  Where  c.leaf_code = f.relation_code)
Union All
Select '責任中心表示為支行但是無對應賬戶' ct
      ,'責任中心表示為支行但是無對應賬戶' cc
      ,e.org_l1
      ,e.org_l1_desc
      ,e.org_l2
      ,e.org_l2_desc
      ,c.leaf_code
      ,c.leaf_desc
      ,nvl(b.occur_bal,
             0) occur_bal
From   vw_cost_center c
      ,ledger_occur   b
      ,org_l2         e
Where  Not Exists (Select 1
  From   instrument_table d
  Where  c.leaf_code = d.org_unit_id)
 And c.opt_txt1 = 'BR'
 And c.opt_txt20 = e.org_l2
 And c.leaf_code = b.cost_center)
order by org_l1,org_l2,ct,cc

先用我定製的這個SQL語句來獲取PLAN中所有的表的資訊(使用中遇到問題請留言告知,謝謝):

WITH X AS
 (SELECT /*+ MATERIALIZE */
 OBJECT_OWNER,
 OBJECT_NAME,
 LISTAGG(OBJECT_ALIAS, ' | ') WITHIN GROUP(ORDER BY OBJECT_NAME) OBJECT_ALIAS,
 OBJECT_TYPE
  FROM (SELECT OBJECT_OWNER,
               OBJECT_NAME,
               CASE
                 WHEN OBJECT_TYPE LIKE 'TABLE%' THEN
                  SUBSTR(OBJECT_ALIAS, 1, INSTR(OBJECT_ALIAS, '@') - 1)
                 ELSE
                  'NOALIAS'
               END OBJECT_ALIAS,
               OBJECT_TYPE,
               TIMESTAMP,
               MAX(TIMESTAMP) OVER(ORDER BY TIMESTAMP DESC) AS MAX_TIME
          FROM PLAN_TABLE
         WHERE OBJECT_NAME IS NOT NULL)
 WHERE TIMESTAMP = MAX_TIME
 GROUP BY OBJECT_NAME, OBJECT_OWNER, OBJECT_TYPE),
Z AS
 (SELECT B.OWNER,
         X.OBJECT_TYPE,
         B.SEGMENT_NAME OBJECT_NAME,
         X.OBJECT_ALIAS ALIAS,
         C.PARTITIONED,
         CASE
           WHEN C.PARTITIONED = 'YES' THEN
            SUM(B.BYTES / 1024 / 1024) OVER(PARTITION BY C.TABLE_NAME)
           ELSE
            B.BYTES / 1024 / 1024
         END SIZE_MB,
         C.NUM_ROWS,
         TRUNC(D.SAMPLE_SIZE / DECODE(D.NUM_ROWS, 0, 1, D.NUM_ROWS) * 100) || '%' ESTIMATE_PERCENT,
         D.LAST_ANALYZED,
         CASE
           WHEN D.STALE_STATS = 'YES' OR D.LAST_ANALYZED IS NULL THEN
            '統計資訊過期'
           ELSE
            '統計資訊未過期'
         END STATUS,
         ROW_NUMBER() OVER(PARTITION BY D.TABLE_NAME ORDER BY D.PARTITION_NAME) FLAG
    FROM DBA_SEGMENTS B, DBA_TABLES C, DBA_TAB_STATISTICS D, X
   WHERE B.OWNER || B.SEGMENT_NAME || B.PARTITION_NAME =
         D.OWNER || D.TABLE_NAME || D.PARTITION_NAME
     AND D.OWNER || D.TABLE_NAME = C.OWNER || C.TABLE_NAME
     AND B.OWNER || B.SEGMENT_NAME || SUBSTR(B.SEGMENT_TYPE, 1, 5) =
         X.OBJECT_OWNER || OBJECT_NAME ||SUBSTR(X.OBJECT_TYPE,1,5)
     AND B.SEGMENT_TYPE LIKE 'TABLE%'
     AND B.SEGMENT_NAME NOT LIKE '%BIN$%'
  UNION ALL
  SELECT B.OWNER,
         X.OBJECT_TYPE,
         B.SEGMENT_NAME OBJECT_NAME,
         X.OBJECT_ALIAS ALIAS,
         C.PARTITIONED,
         CASE
           WHEN C.PARTITIONED = 'YES' THEN
            SUM(B.BYTES / 1024 / 1024) OVER(PARTITION BY C.INDEX_NAME)
           ELSE
            B.BYTES / 1024 / 1024
         END SIZE_MB,
         C.NUM_ROWS,
         TRUNC(D.SAMPLE_SIZE / DECODE(D.NUM_ROWS, 0, 1, D.NUM_ROWS) * 100) || '%' ESTIMATE_PERCENT,
         D.LAST_ANALYZED,
         CASE
           WHEN D.STALE_STATS = 'YES' OR D.LAST_ANALYZED IS NULL THEN
            '統計資訊過期'
           ELSE
            '統計資訊未過期'
         END STATUS,
         ROW_NUMBER() OVER(PARTITION BY D.TABLE_NAME ORDER BY D.PARTITION_NAME) FLAG
    FROM DBA_SEGMENTS B, DBA_INDEXES C, DBA_IND_STATISTICS D, X
   WHERE B.OWNER || B.SEGMENT_NAME || B.PARTITION_NAME =
         D.OWNER || D.INDEX_NAME || D.PARTITION_NAME
     AND D.OWNER || D.INDEX_NAME = C.OWNER || C.INDEX_NAME
     AND B.OWNER || B.SEGMENT_NAME || SUBSTR(B.SEGMENT_TYPE, 1, 5) =
         X.OBJECT_OWNER || OBJECT_NAME ||SUBSTR(X.OBJECT_TYPE,1,5)
     AND B.SEGMENT_TYPE LIKE 'INDEX%'
     AND B.SEGMENT_NAME NOT LIKE '%BIN$%')
SELECT OWNER,
       OBJECT_TYPE,
       OBJECT_NAME,
       ALIAS,
       PARTITIONED,
       SIZE_MB,
       NUM_ROWS,
       ESTIMATE_PERCENT,
       LAST_ANALYZED,
       STATUS
  FROM Z
 WHERE FLAG = 1;
結果如下:

首先:這個視圖裡面有order by,我在上一篇文章裡面說過,視圖裡面的order by沒意義,直接去掉!!!!!

根據上面表資訊可以看出  這裡面唯一的大表INSTRUMENT_TABLE  被訪問了兩次,然後能稱得上大的表就是WRK_ACCT_MGR和SMG_WRK_RELATION。PLAN對這3個表的處理方式,決定了整個SQL效能的優劣。【小表無論走什麼訪問路徑和連線方式都不可能引起效能問題】

所以我們把這幾個表所在的SQL單拿出來,只需要分析這部分的SQL即可

第一段SQL和PLAN如下:

With val_yxtd As
  (  select /*+ parallel(aa,4) +*/ *
  from smg_wrk_relation aa
  where exists
  (select 1 from wrk_acct_mgr a
  inner join instrument_table b
  on  substr(a.acct_no,1,16) = substr(b.cust_acct_no,1,16)
  where  a.mgr_code = aa.orgin_code1
  and a.org_l2 = aa.orgin_code2
  )
  and  aa.relation_type = 'cc_mgr')

Plan hash value: 247310325
 
----------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                | Name               | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                         |                    |   297K|   328M|       |   412K  (1)| 01:22:34 |        |      |            |
|   1 |  PX COORDINATOR                          |                    |       |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)                    | :TQ10003           |   297K|   328M|       |   412K  (1)| 01:22:34 |  Q1,03 | P->S | QC (RAND)  |
|   3 |    VIEW                                  | VM_NWVW_2          |   297K|   328M|       |   412K  (1)| 01:22:34 |  Q1,03 | PCWP |            |
|   4 |     HASH UNIQUE                          |                    |   297K|    49M|    51M|   412K  (1)| 01:22:34 |  Q1,03 | PCWP |            |
|   5 |      PX RECEIVE                          |                    |   297K|    49M|       |   412K  (1)| 01:22:34 |  Q1,03 | PCWP |            |
|   6 |       PX SEND HASH                       | :TQ10002           |   297K|    49M|       |   412K  (1)| 01:22:34 |  Q1,02 | P->P | HASH       |
|   7 |        HASH UNIQUE                       |                    |   297K|    49M|    51M|   412K  (1)| 01:22:34 |  Q1,02 | PCWP |            |
|*  8 |         FILTER                	         |                    |   297K|    49M|       |   412K  (1)| 01:22:34 |  Q1,02 | PCWP |            |
|   9 |          PX RECEIVE                      |                    |   260K|    39M|       | 57333   (1)| 00:11:28 |  Q1,02 | PCWP |            |
|  10 |           PX SEND HASH                   | :TQ10001           |   260K|    39M|       | 57333   (1)| 00:11:28 |  Q1,01 | P->P | HASH       |
|  11 |            FILTER                        |                    |   260K|    39M|       | 57333   (1)| 00:11:28 |  Q1,01 | PCWP |            |
|  12 |             FILTER               	 |                    |   261K|    39M|       | 57333   (1)| 00:11:28 |  Q1,01 | PCWP |            |
|  13 |              PX BLOCK ITERATOR           |                    |       |       |       |            |          |  Q1,01 | PCWC |            |
|  14 |               TABLE ACCESS BY INDEX ROWID| SMG_WRK_RELATION   | 32717 |  3929K|       |  1916   (1)| 00:00:23 |  Q1,01 | PCWP |            |
|* 15 |                INDEX RANGE SCAN          | IN_SMG_RELATION_01 |     8 |       |       |     6   (0)| 00:00:01 |  Q1,01 | PCWP |            |
|* 16 |              INDEX RANGE SCAN            | IN_WRK_ACCT_MGR_01 |     8 |       |       |     6   (0)| 00:00:01 |  Q1,01 | PCWP |            |
|  17 |             TABLE ACCESS BY INDEX ROWID  | WRK_ACCT_MGR       |     8 |   280 |       |     9   (0)| 00:00:01 |  Q1,01 | PCWP |            |
|  18 |          BUFFER SORT                     |                    |       |       |       |            |          |  Q1,02 | PCWC |            |
|  19 |           PX RECEIVE                     |                    |    26M|   404M|       |   355K  (1)| 01:11:05 |  Q1,02 | PCWP |            |
|  20 |            PX SEND HASH                  | :TQ10000           |    26M|   404M|       |   355K  (1)| 01:11:05 |        | S->P | HASH       |
|  21 |             TABLE ACCESS FULL            | INSTRUMENT_TABLE   |    26M|   404M|       |   355K  (1)| 01:11:05 |        |      |            |
--------------------------------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   8 - access(SUBSTR("ACCT_NO",1,16)=SUBSTR("B"."CUST_ACCT_NO",1,16))
  15 - filter("AA"."RELATION_TYPE"='cc_mgr')
  16 - access("AA"."ORGIN_CODE2"="A"."ORG_L2" AND "AA"."ORGIN_CODE1"="A"."MGR_CODE")
 
Note
-----
   - dynamic sampling used for this statement (level=6)
這個SQL所涉及的三個表正好都是我上述所說的大表。這個SQL最終返回3w行,走filter顯然不是很好

1.第15步aa.relation_type = 'cc_mgr' 走index range scan後返回3w條資料(aa表總共135w+條資料),看上去還算合理,但是需要3w次回表(第14步),3w次回表是一筆不小的cost
2.aa表作為驅動表去驅動a表返回結果同樣需要 回表3w次
3.最坑爹的是aa表和a表nl的結果集作為驅動表去驅動b表,關聯條件substr(a.acct_no,1,16) = substr(b.cust_acct_no,1,16),被驅動表b無法走索引
只能走全表。也就是說這個2600w行佔用空間11GB的b表需要被table access full 3w次.。。。。。這是一件很恐怖的事情。

所以這個SQL優化的主要手段就是消除FILTER或者NL,因為一旦走了這種“傳值類”的連線方式。b表就需要被掃描3w+次。當然最好的方式就是走hash連線,大表只掃一次。

FILTER產生的原因有很多,諸如 子查詢裡面有主查詢的過濾條件、or exists、子查詢被固化等等。但是這裡面的FILTER並不是因為SQL的寫法引起的,而是CBO認為最好的連線方式

根據我的經驗 exists/not exists 這種傳值類產生FILTER的概率比in/not in高,當然需要排除子查詢裡面出現NULL的情況。所以我個人比較推薦半連線/反連線用in/not in代替exists/not exists。所以將這段SQL改寫如下,

其實就算我不改寫也可以用hint的方式使其走hash連線。我改寫的目的只是為了說明in/not in可以走正常執行計劃。

  With val_yxtd As
  ( select /*+ materialize full(aa) parallel(aa 4)*/ *
  from smg_wrk_relation aa
  where (aa.orgin_code1,aa.orgin_code2) in(select a.mgr_code,a.org_l2 from wrk_acct_mgr a
  inner join instrument_table b
  on  substr(a.acct_no,1,16) = substr(b.cust_acct_no,1,16))
  and  aa.relation_type = 'cc_mgr'
表aa走table access full比走索引+回表的效率要高。 我這裡加了full(aa) 的hint 

這一段SQL總共返回3w行資料,所以加materialize hint固化,可以把這個結果資料量小的結果集作為臨時表(當這個結果集被引用1次以上的時候會自動固化結果集)

第二段SQL和PLAN如下:

Select '責任中心表示為支行但是無對應賬戶' ct
      ,'責任中心表示為支行但是無對應賬戶' cc
      ,e.org_l1
      ,e.org_l1_desc
      ,e.org_l2
      ,e.org_l2_desc
      ,c.leaf_code
      ,c.leaf_desc
      ,nvl(b.occur_bal,
             0) occur_bal
From   vw_cost_center c
      ,ledger_occur   b
      ,org_l2         e
Where  Not Exists (Select 1
  From   instrument_table d
  Where  c.leaf_code = d.org_unit_id)
 And c.opt_txt1 = 'BR'
 And c.opt_txt20 = e.org_l2
 And c.leaf_code = b.cost_center)
Plan hash value: 3375556997
 
------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name                        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |                             |     2 |  1910 |       |   356K  (1)| 01:11:22 |
|   1 |  TEMP TABLE TRANSFORMATION |                             |       |       |       |            |          |
|   2 |   LOAD AS SELECT           | SYS_TEMP_0FDA48FE9_26499B86 |       |       |       |            |          |
|   3 |    HASH GROUP BY           |                             |   348 | 22620 |       |   896   (2)| 00:00:11 |
|*  4 |     HASH JOIN RIGHT OUTER  |                             | 54301 |  3446K|       |   893   (1)| 00:00:11 |
|*  5 |      TABLE ACCESS FULL     | SMG_DEF_LEVES               |    14 |   728 |       |    68   (0)| 00:00:01 |
|*  6 |      TABLE ACCESS FULL     | LEDGER_STAT                 | 54301 |   689K|       |   824   (1)| 00:00:10 |
|   7 |   LOAD AS SELECT           | SYS_TEMP_0FDA48FEA_26499B86 |       |       |       |            |          |
|   8 |    HASH UNIQUE             |                             |  4125 |  2578K|  2760K|   576   (1)| 00:00:07 |
|   9 |     TABLE ACCESS FULL      | DIM_TREE_3                  |  4125 |  2578K|       |    15   (0)| 00:00:01 |
|* 10 |   HASH JOIN                |                             |     2 |  1910 |       |   355K  (1)| 01:11:04 |
|* 11 |    HASH JOIN               |                             |     1 |   315 |       |   355K  (1)| 01:11:03 |
|* 12 |     HASH JOIN ANTI         |                             |     1 |    44 |       |   355K  (1)| 01:11:03 |
|* 13 |      TABLE ACCESS FULL     | SMG_DEF_LEVES               |   124 |  4712 |       |    68   (0)| 00:00:01 |
|  14 |      TABLE ACCESS FULL     | INSTRUMENT_TABLE            |    26M|   151M|       |   355K  (1)| 01:11:01 |
|  15 |     VIEW                   |                             |   348 | 94308 |       |     3   (0)| 00:00:01 |
|  16 |      TABLE ACCESS FULL     | SYS_TEMP_0FDA48FE9_26499B86 |   348 | 22620 |       |     3   (0)| 00:00:01 |
|  17 |    VIEW                    |                             |  4125 |  2578K|       |    99   (0)| 00:00:02 |
|  18 |     TABLE ACCESS FULL      | SYS_TEMP_0FDA48FEA_26499B86 |  4125 |  2578K|       |    99   (0)| 00:00:02 |
------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   4 - access("L"."LEAF_CODE"(+)="COST_CENTER")
   5 - filter("L"."OPT_TXT10"(+) IS NOT NULL AND "L"."FIELD_ID"(+)=8)
   6 - filter("SRC_ID"='SG')
  10 - access("OPT_TXT20"="E"."ORG_L2")
  11 - access("LEAF_CODE"="B"."COST_CENTER")
  12 - access("LEAF_CODE"="D"."ORG_UNIT_ID")
  13 - filter("OPT_TXT20" IS NOT NULL AND "OPT_TXT1"='BR' AND "FIELD_ID"=8)
 
Note
-----
   - dynamic sampling used for this statement (level=2)


上面SQL 所涉及表的大小如下:
vw_cost_center 4335
ledger_occur   2521
org_l2         105
所以這個SQL的主要消耗在INSTRUMENT_TABLE的TABLE ACCESS FULL所以PLAN沒問題.(如果其他幾個表都是引數表,讓INSTRUMENT_TABLE作為驅動表效率更高)


優化完之後整個檢視1s就出結果,引用到這個檢視的前臺頁面查詢SQL也集體“得救”,最終的SQL和PLAN如下:

select ct 檢查型別
 ,cc          錯誤型別
      ,org_l1            一級行編碼
      ,org_l1_desc       一級行說明
      ,org_l2            二級行編碼
      ,org_l2_desc        二級行說明
      ,leaf_code   責任中心編碼
      ,leaf_desc 責任中心說明
      ,occur_bal         發生額
      from
(With val_yxtd As
  ( select /*+ materialize full(aa) parallel(aa 4)*/ *
  from smg_wrk_relation aa
  where (aa.orgin_code1,aa.orgin_code2) in(select a.mgr_code,a.org_l2 from wrk_acct_mgr a
  inner join instrument_table b
  on  substr(a.acct_no,1,16) = substr(b.cust_acct_no,1,16))
  and  aa.relation_type = 'cc_mgr'),
ledger_occur As
 (select/*+ materialize */ nvl(l.opt_txt10,cost_center) cost_center,occur_bal from (
 Select cost_center
        ,Sum(occur_bal) occur_bal
  From   ledger_stat
  Where  src_id = 'SG'
  Group  By cost_center) m
  left join smg_def_leves l --表中維護總賬成本落在金融工具表中經營主體 對應opt_txt10欄位維護
on l.leaf_code=m.cost_center
and l.field_id=8 and l.opt_txt10 is not null),--459089.36,

org_l2 As
 (Select /*+ materialize */Distinct level_01_code org_l1
                 ,level_01_desc org_l1_desc
                 ,level_02_code org_l2
                 ,level_02_desc org_l2_desc
  From   dim_tree_3)
Select '責任中心為營銷團隊但無有效賬戶' ct
      ,'沒有維護營銷團隊與客戶經理關係的資料' cc
      ,e.org_l1
      ,e.org_l1_desc
      ,e.org_l2
      ,e.org_l2_desc
      ,c.leaf_code
      ,c.leaf_desc
      ,nvl(b.occur_bal,
           0) occur_bal
From   vw_cost_center c
      ,org_l2         e
      ,ledger_occur   b
Where  c.opt_txt1 = 'MK'
And    c.opt_txt20 = e.org_l2
And    c.leaf_code = b.cost_center(+)
And    Not Exists (Select 1
        From   smg_wrk_relation f
        Where  c.leaf_code = f.relation_code
        And    f.relation_type = 'cc_mgr')
Union All
Select '責任中心為營銷團隊但無有效賬戶' ct
      ,'維護營銷團隊與客戶經理關係,但仍不存在有效賬戶的資料' cc
      ,e.org_l1
      ,e.org_l1_desc
      ,e.org_l2
      ,e.org_l2_desc
      ,c.leaf_code
      ,c.leaf_desc
      ,nvl(b.occur_bal,
            0) occur_bal
From   vw_cost_center c
      ,org_l2         e
      ,ledger_occur   b
Where  c.opt_txt1 = 'MK'
 And c.opt_txt20 = e.org_l2
 And c.leaf_code = b.cost_center(+)
 And Exists (Select 1
  From   smg_wrk_relation f
  Where  c.leaf_code = f.relation_code
  And    f.relation_type = 'cc_mgr')
 And Not Exists (Select 1
  From   val_yxtd f
  Where  c.leaf_code = f.relation_code)
Union All
Select '責任中心表示為支行但是無對應賬戶' ct
      ,'責任中心表示為支行但是無對應賬戶' cc
      ,e.org_l1
      ,e.org_l1_desc
      ,e.org_l2
      ,e.org_l2_desc
      ,c.leaf_code
      ,c.leaf_desc
      ,nvl(b.occur_bal,
             0) occur_bal
From   vw_cost_center c
      ,ledger_occur   b
      ,org_l2         e
Where  Not Exists (Select 1
  From   instrument_table d
  Where  c.leaf_code = d.org_unit_id)
 And c.opt_txt1 = 'BR'
 And c.opt_txt20 = e.org_l2
 And c.leaf_code = b.cost_center);
 

Plan hash value: 3264994889
 
------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name                        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |                             | 15833 |    15M|       |   375K  (1)| 01:15:06 |        |      |            |
|   1 |  TEMP TABLE TRANSFORMATION              |                             |       |       |       |            |          |        |      |            |
|   2 |   PX COORDINATOR                        |                             |       |       |       |            |          |        |      |            |
|   3 |    PX SEND QC (RANDOM)                  | :TQ10002                    | 32717 |    16M|       |   622K  (1)| 02:04:35 |  Q1,02 | P->S | QC (RAND)  |
|   4 |     LOAD AS SELECT                      | SYS_TEMP_0FDA48FF1_26499B86 |       |       |       |            |          |  Q1,02 | PCWP |            |
|*  5 |      HASH JOIN SEMI                     |                             | 32717 |    16M|       |   622K  (1)| 02:04:35 |  Q1,02 | PCWP |            |
|   6 |       PX RECEIVE                        |                             | 32717 |  3929K|       |  1916   (1)| 00:00:23 |  Q1,02 | PCWP |            |
|   7 |        PX SEND HASH                     | :TQ10001                    | 32717 |  3929K|       |  1916   (1)| 00:00:23 |  Q1,01 | P->P | HASH       |
|   8 |         PX BLOCK ITERATOR               |                             | 32717 |  3929K|       |  1916   (1)| 00:00:23 |  Q1,01 | PCWC |            |
|*  9 |          TABLE ACCESS FULL              | SMG_WRK_RELATION            | 32717 |  3929K|       |  1916   (1)| 00:00:23 |  Q1,01 | PCWP |            |
|  10 |       BUFFER SORT                       |                             |       |       |       |            |          |  Q1,02 | PCWC |            |
|  11 |        PX RECEIVE                       |                             |    36M|    13G|       |   620K  (1)| 02:04:11 |  Q1,02 | PCWP |            |
|  12 |         PX SEND HASH                    | :TQ10000                    |    36M|    13G|       |   620K  (1)| 02:04:11 |        | S->P | HASH       |
|  13 |          VIEW                           | VW_NSO_1                    |    36M|    13G|       |   620K  (1)| 02:04:11 |        |      |            |
|* 14 |           HASH JOIN                     |                             |    36M|  1797M|   707M|   620K  (1)| 02:04:11 |        |      |            |
|  15 |            TABLE ACCESS FULL            | INSTRUMENT_TABLE            |    26M|   404M|       |   355K  (1)| 01:11:05 |        |      |            |
|  16 |            TABLE ACCESS FULL            | WRK_ACCT_MGR                |    32M|  1082M|       |   157K  (1)| 00:31:34 |        |      |            |
|  17 |   LOAD AS SELECT                        | SYS_TEMP_0FDA48FF2_26499B86 |       |       |       |            |          |        |      |            |
|  18 |    HASH GROUP BY                        |                             |     1 |    91 |       |   896   (2)| 00:00:11 |        |      |            |
|* 19 |     HASH JOIN RIGHT OUTER               |                             | 54301 |  4825K|       |   893   (1)| 00:00:11 |        |      |            |
|* 20 |      TABLE ACCESS FULL                  | SMG_DEF_LEVES               |     2 |   156 |       |    68   (0)| 00:00:01 |        |      |            |
|* 21 |      TABLE ACCESS FULL                  | LEDGER_STAT                 | 54301 |   689K|       |   824   (1)| 00:00:10 |        |      |            |
|  22 |   LOAD AS SELECT                        | SYS_TEMP_0FDA48FF3_26499B86 |       |       |       |            |          |        |      |            |
|  23 |    HASH UNIQUE                          |                             |  4125 |  2578K|  2760K|   576   (1)| 00:00:07 |        |      |            |
|  24 |     TABLE ACCESS FULL                   | DIM_TREE_3                  |  4125 |  2578K|       |    15   (0)| 00:00:01 |        |      |            |
|  25 |   PX COORDINATOR                        |                             |       |       |       |            |          |        |      |            |
|  26 |    PX SEND QC (RANDOM)                  | :TQ20007                    | 15833 |    15M|       |   375K  (1)| 01:15:06 |  Q2,07 | P->S | QC (RAND)  |
|  27 |     BUFFER SORT                         |                             | 15833 |    15M|       |            |          |  Q2,07 | PCWP |            |
|  28 |      VIEW                               |                             | 15833 |    15M|       |   375K  (1)| 01:15:06 |  Q2,07 | PCWP |            |
|  29 |       UNION-ALL                         |                             |       |       |       |            |          |  Q2,07 | PCWP |            |
|  30 |        BUFFER SORT                      |                             |       |       |       |            |          |  Q2,07 | PCWC |            |
|  31 |         PX RECEIVE                      |                             |       |       |       |            |          |  Q2,07 | PCWP |            |
|  32 |          PX SEND ROUND-ROBIN            | :TQ20002                    |       |       |       |            |          |        | S->P | RND-ROBIN  |
|* 33 |           FILTER                        |                             |       |       |       |            |          |        |      |            |
|* 34 |            HASH JOIN                    |                             | 15677 |    14M|       |   170   (1)| 00:00:03 |        |      |            |
|* 35 |             HASH JOIN RIGHT OUTER       |                             |   485 |   146K|       |    71   (2)| 00:00:01 |        |      |            |
|  36 |              VIEW                       |                             |     1 |   271 |       |     2   (0)| 00:00:01 |        |      |            |
|  37 |               TABLE ACCESS FULL         | SYS_TEMP_0FDA48FF2_26499B86 |     1 |    91 |       |     2   (0)| 00:00:01 |        |      |            |
|* 38 |              TABLE ACCESS FULL          | SMG_DEF_LEVES               |   485 | 18430 |       |    68   (0)| 00:00:01 |        |      |            |
|  39 |             VIEW                        |                             |  4125 |  2578K|       |    99   (0)| 00:00:02 |        |      |            |
|  40 |              TABLE ACCESS FULL          | SYS_TEMP_0FDA48FF3_26499B86 |  4125 |  2578K|       |    99   (0)| 00:00:02 |        |      |            |
|* 41 |            INDEX RANGE SCAN             | IN_SMG_WRK_RELATION         |     6 |   102 |       |     3   (0)| 00:00:01 |        |      |            |
|* 42 |        HASH JOIN                        |                             |   157 |   157K|       |   349   (1)| 00:00:05 |  Q2,07 | PCWP |            |
|  43 |         PX RECEIVE                      |                             |     5 |  1940 |       |   250   (1)| 00:00:04 |  Q2,07 | PCWP |            |
|  44 |          PX SEND HASH                   | :TQ20006                    |     5 |  1940 |       |   250   (1)| 00:00:04 |  Q2,06 | P->P | HASH       |
|  45 |           NESTED LOOPS SEMI             |                             |     5 |  1940 |       |   250   (1)| 00:00:04 |  Q2,06 | PCWP |            |
|* 46 |            HASH JOIN OUTER              |                             |     5 |  1855 |       |   247   (1)| 00:00:03 |  Q2,06 | PCWP |            |
|* 47 |             HASH JOIN ANTI              |                             |     5 |   500 |       |   245   (1)| 00:00:03 |  Q2,06 | PCWP |            |
|  48 |              BUFFER SORT                |                             |       |       |       |            |          |  Q2,06 | PCWC |            |
|  49 |               PX RECEIVE                |                             |   485 | 18430 |       |    68   (0)| 00:00:01 |  Q2,06 | PCWP |            |
|  50 |                PX SEND HASH             | :TQ20000                    |   485 | 18430 |       |    68   (0)| 00:00:01 |        | S->P | HASH       |
|* 51 |                 TABLE ACCESS FULL       | SMG_DEF_LEVES               |   485 | 18430 |       |    68   (0)| 00:00:01 |        |      |            |
|  52 |              PX RECEIVE                 |                             | 32717 |  1980K|       |   177   (1)| 00:00:03 |  Q2,06 | PCWP |            |
|  53 |               PX SEND HASH              | :TQ20005                    | 32717 |  1980K|       |   177   (1)| 00:00:03 |  Q2,05 | P->P | HASH       |
|  54 |                VIEW                     |                             | 32717 |  1980K|       |   177   (1)| 00:00:03 |  Q2,05 | PCWP |            |
|  55 |                 PX BLOCK ITERATOR       |                             | 32717 |  4568K|       |   177   (1)| 00:00:03 |  Q2,05 | PCWC |            |
|  56 |                  TABLE ACCESS FULL      | SYS_TEMP_0FDA48FF1_26499B86 | 32717 |  4568K|       |   177   (1)| 00:00:03 |  Q2,05 | PCWP |            |
|  57 |             BUFFER SORT                 |                             |       |       |       |            |          |  Q2,06 | PCWC |            |
|  58 |              PX RECEIVE                 |                             |     1 |   271 |       |     2   (0)| 00:00:01 |  Q2,06 | PCWP |            |
|  59 |               PX SEND HASH              | :TQ20001                    |     1 |   271 |       |     2   (0)| 00:00:01 |        | S->P | HASH       |
|  60 |                VIEW                     |                             |     1 |   271 |       |     2   (0)| 00:00:01 |        |      |            |
|  61 |                 TABLE ACCESS FULL       | SYS_TEMP_0FDA48FF2_26499B86 |     1 |    91 |       |     2   (0)| 00:00:01 |        |      |            |
|* 62 |            INDEX RANGE SCAN             | IN_SMG_WRK_RELATION         | 32717 |   543K|       |     2   (0)| 00:00:01 |  Q2,06 | PCWP |            |
|  63 |         BUFFER SORT                     |                             |       |       |       |            |          |  Q2,07 | PCWC |            |
|  64 |          PX RECEIVE                     |                             |  4125 |  2578K|       |    99   (0)| 00:00:02 |  Q2,07 | PCWP |            |
|  65 |           PX SEND HASH                  | :TQ20003                    |  4125 |  2578K|       |    99   (0)| 00:00:02 |        | S->P | HASH       |
|  66 |            VIEW                         |                             |  4125 |  2578K|       |    99   (0)| 00:00:02 |        |      |            |
|  67 |             TABLE ACCESS FULL           | SYS_TEMP_0FDA48FF3_26499B86 |  4125 |  2578K|       |    99   (0)| 00:00:02 |        |      |            |
|  68 |        BUFFER SORT                      |                             |       |       |       |            |          |  Q2,07 | PCWC |            |
|  69 |         PX RECEIVE                      |                             |     1 |   955 |       |   355K  (1)| 01:11:03 |  Q2,07 | PCWP |            |
|  70 |          PX SEND ROUND-ROBIN            | :TQ20004                    |     1 |   955 |       |   355K  (1)| 01:11:03 |        | S->P | RND-ROBIN  |
|* 71 |           HASH JOIN                     |                             |     1 |   955 |       |   355K  (1)| 01:11:03 |        |      |            |
|* 72 |            HASH JOIN ANTI               |                             |     1 |   315 |       |   355K  (1)| 01:11:02 |        |      |            |
|  73 |             NESTED LOOPS                |                             |     1 |   309 |       |     3   (0)| 00:00:01 |        |      |            |
|  74 |              NESTED LOOPS               |                             |     1 |   309 |       |     3   (0)| 00:00:01 |        |      |            |
|  75 |               VIEW                      |                             |     1 |   271 |       |     2   (0)| 00:00:01 |        |      |            |
|  76 |                TABLE ACCESS FULL        | SYS_TEMP_0FDA48FF2_26499B86 |     1 |    91 |       |     2   (0)| 00:00:01 |        |      |            |
|* 77 |               INDEX UNIQUE SCAN         | PK_SMG_DEF_LEVES            |     1 |       |       |     0   (0)| 00:00:01 |        |      |            |
|* 78 |              TABLE ACCESS BY INDEX ROWID| SMG_DEF_LEVES               |     1 |    38 |       |     1   (0)| 00:00:01 |        |      |            |
|  79 |             TABLE ACCESS FULL           | INSTRUMENT_TABLE            |    26M|   151M|       |   355K  (1)| 01:11:01 |        |      |            |
|  80 |            VIEW                         |                             |  4125 |  2578K|       |    99   (0)| 00:00:02 |        |      |            |
|  81 |             TABLE ACCESS FULL           | SYS_TEMP_0FDA48FF3_26499B86 |  4125 |  2578K|       |    99   (0)| 00:00:02 |        |      |            |
------------------------------------------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   5 - access("AA"."ORGIN_CODE1"="MGR_CODE" AND "AA"."ORGIN_CODE2"="ORG_L2")
   9 - filter("AA"."RELATION_TYPE"='cc_mgr')
  14 - access(SUBSTR("ACCT_NO",1,16)=SUBSTR("B"."CUST_ACCT_NO",1,16))
  19 - access("L"."LEAF_CODE"(+)="COST_CENTER")
  20 - filter("L"."OPT_TXT10"(+) IS NOT NULL AND "L"."FIELD_ID"(+)=8)
  21 - filter("SRC_ID"='SG')
  33 - filter( NOT EXISTS (SELECT 0 FROM "ANNE_MAIN"."SMG_WRK_RELATION" "F" WHERE "F"."RELATION_CODE"=:B1 AND "F"."RELATION_TYPE"='cc_mgr'))
  34 - access("OPT_TXT20"="E"."ORG_L2")
  35 - access("LEAF_CODE"="B"."COST_CENTER"(+))
  38 - filter("OPT_TXT20" IS NOT NULL AND "OPT_TXT1"='MK' AND "FIELD_ID"=8)
  41 - access("F"."RELATION_TYPE"='cc_mgr' AND "F"."RELATION_CODE"=:B1)
  42 - access("OPT_TXT20"="E"."ORG_L2")
  46 - access("LEAF_CODE"="B"."COST_CENTER"(+))
  47 - access("LEAF_CODE"="F"."RELATION_CODE")
  51 - filter("OPT_TXT20" IS NOT NULL AND "OPT_TXT1"='MK' AND "FIELD_ID"=8)
  62 - access("F"."RELATION_TYPE"='cc_mgr' AND "LEAF_CODE"="F"."RELATION_CODE")
  71 - access("OPT_TXT20"="E"."ORG_L2")
  72 - access("LEAF_CODE"="D"."ORG_UNIT_ID")
  77 - access("LEAF_CODE"="B"."COST_CENTER" AND "FIELD_ID"=8)
  78 - filter("OPT_TXT20" IS NOT NULL AND "OPT_TXT1"='BR')
 
Note
-----
   - dynamic sampling used for this statement (level=6)

總結:

優化,一定要找SQL的效能瓶頸部分。把瓶頸搞定了,雖然這個PLAN可能不是最優的,但也絕對不會引起大的效能問題。 優化就是要搞定最突出的問題,而絕不是錦上添花。。。。

優化SQL,一定要找大表,因為只能大表才可能引起效能問題。優化之前獲取這個SQL裡面所有表的資訊有助於你更快定位效能瓶頸


相關推薦

一個結果檢視優化

作為銀行乙方開發DBA,職責之一就是每個月都給銀行各個系統出一份效能優化報告 連續給某個系統優化了好幾條坑爹的大SQL之後,介面人今天找到我說 有一個檢視從建立開始 和這個檢視相關的SQL從來沒有跑出來過。最長的一次跑了24小時沒出結果。檢視單跑也是2個小時跑不出來 使用者

MRP結果解決全過程

今天需要測試40策略的結果 修改了主資料,10策略為40策略 建立了銷售訂單(CP參與MPR運算) MD04能看到就是跑不出結果(貌似遇到看不到情況,檢查是否就交貨完成 或沒參與MPR運算--訂單CN  訂單倉位沒納入MRP運算) 新建一個料號和那個料號一樣 把料號加到

MySQL自定義函數調用結果

ble Staff name adding return 狀態 調用函數 mage size 自定義函數的代碼: DROP FUNCTION IF EXISTS fn_HrStaffBase_GetNameFromidCard delimiter //CREATE FUNC

tensorflow objectdetecton API 檢測模型結果

檢測模型 在經過上萬次迭代訓練自己的樣本後,嘗試檢測模型;用相似環境下的圖片作為檢測樣本。 以下是檢測程式碼,copy自別處,修改自己的路徑一類,cmd下執行,或者在配置好環境的pycharm 下執行。 import matplotlib matplotlib.use('Agg')

pycharm執行正確但是結果

描述:之前用的好好的,突然有一天用pycharm執行程式,明明結果正確, 打印不出來結果,看下圖   解決: 1、檢視File Transfer有好多錯誤,意思是沒有連線上伺服器 [2018/12/8 21:05] Automatic upload failed: could not c

hibernate+mysql中文查詢結果,其他查詢正常,SQL語句也正常

做一個專案hibernate+MySQL資料庫,Java後臺全部正常,檢視Java想資料庫傳送的語句也是正常的,但是中文就是查詢不出結果,中文在Java中沒有亂碼,用new String(or_n

Hibernate hql 中文查詢 查結果

hql沒問題了,但就是差不出結果,還不報錯…… 是中文編碼問題。 最簡單方法: 連線sql語句改為: jdbc:mysql://localhost:3306/XXX?useUnicode=true&characterEncoding=UTF-8

程式碼在pycharm中一直執行結果,求大神指點

我是個python小白,最近正在學習爬蟲,好容易弄出一段爬蟲程式碼,可一直執行不出結果程式碼如下import requests from requests.exceptions import RequestException import re def get_one_pag

同一個sql 在Hive和spark-sql 結果一樣記錄

表Schema hive> desc gdm.dim_category; name string 分類名稱

一個程序員寫代碼了,該怎麽辦?(轉載)

保持 解決 為我 水平 身體 min height 開源 軟件工程 翻譯作者:碼農網-小峰 轉載地址:http://www.codeceo.com/article/what-to-do-programming-sucks.html 原文標題:What Do You Do W

高質量的SEO優化文章是因為沒文采?

今天有位朋友問岑輝宇一個問題,你是如何每天做到寫SEO文章的?筆者思考了一下,回答道:長期的堅持,習慣了。他又問,我該如何寫好SEO優化文章呢?我不假思索的回答道,不斷去實踐和學習。誰知這位朋友說我要有你這樣的文采就好了,我就寫不出這樣的文章出來,我反問了他一句,寫不出高質量的SEO優化文章是

敏捷開發一千零一問系列之三十八:計劃撲克就是打結果怎麼辦?

本文是敏捷開發一千零一問的第三十八篇。(欄目總目錄)問題:一個簡單的問題,計劃撲克就是打不出個結果,各持己見怎麼辦?也就是少數人無法說服大家,或者說根本無人去聽回答:計劃撲克的結束條件”近似一致“是個很有趣的標準,其實要回答”什麼時候停止打撲克“,就要先解決”為什麼要打撲克“

一個好的標題,就用這個吧

問題描述: 某城市最高的樓只有一部電梯。該電梯和一般電梯不同的是它依照輸入樓層數的先後次序執行。電梯最初在0層。執行完一個輸入序列後就停止在該樓層,不返回0層。編寫程式計算電梯執行一個序列的時間。每

一個可以被廣告攔截器攔截的彈視窗

/*** 定義ForceWindow類建構函式* 無引數* 無返回值*/function ForceWindow (){  this.r = document.documentElement;  this.f = document.createElement("FORM");

一個檔案讀取內容計算結果,將結果寫入到另一個檔案中

/* * 專案根路徑下有個questions.txt檔案內容如下: 5+5 [ 5, 5] 150-25 155*155 2555/5 要求:讀取內容計算出結果,將結果寫入到results

Java MyBatis 呼叫聚合函式查詢返回結果示例(記錄下來,方便記得時檢視

mybatis sql配置: <select id="queryFirstResult" resultType="string"> select max(code) as frist

給定一個長度限的字串,請找該字串中出現次數最多的那個字元,並打印該字元及出現次數(C/C++版)

#include<iostream> using namespace std; /** * @brief findchar 給定一個長度不限的字串,請找出該字串中出現次數最多的那個字元,並打印出該字元及出現次數; 如果多個字元的出現次數相同,只打印首個

我的第一個javascript程式--alert為何彈資料?

       今天啃的一本javascript的書籍,著手試了一個入門小例子,但我遇到了一個問題:最簡單的alert竟然無法彈出資料。 <!--我的JavaScript學習之路--> <!DOCTYPE html> <html> <

mybatis查詢資料,結果為null

錯誤的結果為: 程式裡面寫的sql語句放在資料庫裡面去查詢能查詢到資料,但是程式裡面查詢時候,返回的結果為null 記錄一下 我出現的原因是: 資料庫的欄位  account_id    account_name java的實體類:accountId   accoun

芝諾悖論:一個得最快的人永遠追得最慢的人

  這是一個非常著名的悖論,而且我相信很多人都聽過。用現代的說法就是:“龜兔賽跑”。這個悖論是義大利哲學家芝諾(Zenon Eleates,約公元前490年-公元前436年)提出的4個關於運動的悖論之一,嘿嘿,一算離現在已經將近2500年了呢!這個悖論當時在學術圈引起了極大的關注,按照一般的思維我們還真難找出