一個跑不出結果的檢視的優化
作為銀行乙方開發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如下:
這個SQL所涉及的三個表正好都是我上述所說的大表。這個SQL最終返回3w行,走filter顯然不是很好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)
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年了呢!這個悖論當時在學術圈引起了極大的關注,按照一般的思維我們還真難找出