标签:
今天一个网友找我帮他优化他负责数据库的SQL,客服反映这个SQL 跑很久,跑了12个小时,最后跑出ORA-01555 ,以报错结束了这个慢SQL的生命。找我帮他优化,OK ,义不容辞。
他们那边数据库环境是Oracle 12C的:
原SQL 及其执行计划为:
explain plan for select count(*) from (select A.service_code, A.accNo, A.phone_no, A.account_type, nvl(B.mtNo, 0) mt from ((select service_code, decode(account_type, '1', super_account_no, account_no) accNo, phone_no, account_type from t_service_order T1 where province_code = '44' and add_months(process_time, free_month) < add_months(sysdate, -12) and charge_type = '2' and exists (select T2.super_account_no, max(T2.commit_date), count(T2.super_account_no) cn from t_pkk_fail T2 where T2.super_account_no = T1.super_account_no and T2.phone_no = T1.phone_no and T2.service_code = T1.service_code and T2.charge_type = '2' group by T2.super_account_no having(count(T2.super_account_no) > round((sysdate - add_months(T1.process_time, T1.free_month)) / 365) and count(T2.super_account_no) > 1))) A left join (select account_no, count(*) mtNo from t_mail_info_mt1 M where province_code = '44' and to_char(trade_date,'YYYYMMDD') >= '20160401' and to_char(trade_date,'YYYYMMDD') < '20160501' group by account_no) B on A.accno = B.account_no)) X where X.mt = 0; PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Plan hash value: 2939529741 ---------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | ---------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 141 | | 529M (1)| 05:44:37 | | | | 1 | SORT AGGREGATE | | 1 | 141 | | | | | | |* 2 | FILTER | | | | | | | | | |* 3 | FILTER | | | | | | | | | |* 4 | HASH JOIN OUTER | | 4752K| 639M| 489M| 1864K (1)| 00:01:13 | | | | 5 | JOIN FILTER CREATE | :BF0000 | 4752K| 435M| | 184K (1)| 00:00:08 | | | | 6 | PARTITION LIST SINGLE | | 4752K| 435M| | 184K (1)| 00:00:08 | 19 | 19 | |* 7 | TABLE ACCESS FULL | T_SERVICE_ORDER | 4752K| 435M| | 184K (1)| 00:00:08 | 19 | 19 | | 8 | VIEW | | 64M| 2767M| | 1481K (1)| 00:00:58 | | | | 9 | HASH GROUP BY | | 64M| 2583M| 4301M| 1481K (1)| 00:00:58 | | | | 10 | JOIN FILTER USE | :BF0000 | 86M| 3462M| | 701K (1)| 00:00:28 | | | | 11 | PARTITION RANGE ITERATOR | | 86M| 3462M| | 701K (1)| 00:00:28 | 4 | 30 | | 12 | PARTITION LIST SINGLE | | 86M| 3462M| | 701K (1)| 00:00:28 | 19 | 19 | |* 13 | TABLE ACCESS FULL | T_MAIL_INFO_MT1 | 86M| 3462M| | 701K (1)| 00:00:28 | KEY | KEY | |* 14 | FILTER | | | | | | | | | | 15 | SORT GROUP BY NOSORT | | 1 | 59 | | 111 (0)| 00:00:01 | | | | 16 | PARTITION LIST ALL | | 1 | 59 | | 111 (0)| 00:00:01 | 1 | 35 | |* 17 | TABLE ACCESS BY LOCAL INDEX ROWID| T_PKK_FAIL | 1 | 59 | | 111 (0)| 00:00:01 | 1 | 35 | |* 18 | INDEX RANGE SCAN | SUPER_ACCT_INDX | 5 | | | 106 (0)| 00:00:01 | 1 | 35 | ---------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter( EXISTS (SELECT 0 FROM "T_PKK_FAIL" "T2" WHERE "T2"."SUPER_ACCOUNT_NO"=:B1 AND "T2"."PHONE_NO"=:B2 AND "T2"."CHARGE_TYPE"=2 AND "T2"."SERVICE_CODE"=:B3 GROUP BY "T2"."SUPER_ACCOUNT_NO" HAVING COUNT(*)>ROUND((SYSDATE@!-ADD_MONTHS(:B4,:B5))/365) AND COUNT(*)>1)) 3 - filter(NVL("B"."MTNO",0)=0) 4 - access("B"."ACCOUNT_NO"(+)=DECODE("ACCOUNT_TYPE",'1',"SUPER_ACCOUNT_NO","ACCOUNT_NO")) 7 - filter("CHARGE_TYPE"=2 AND ADD_MONTHS(INTERNAL_FUNCTION("PROCESS_TIME"),INTERNAL_FUNCTION("FREE_MONTH"))<ADD_MONTHS (SYSDATE@!,-12)) 13 - filter(SYS_OP_BLOOM_FILTER(:BF0000,"ACCOUNT_NO")) 14 - filter(COUNT(*)>ROUND((SYSDATE@!-ADD_MONTHS(:B1,:B2))/365) AND COUNT(*)>1) 17 - filter("T2"."PHONE_NO"=:B1 AND "T2"."CHARGE_TYPE"=2 AND "T2"."SERVICE_CODE"=:B2) 18 - access("T2"."SUPER_ACCOUNT_NO"=:B1)
select count(*) from (select A.service_code, A.accNo, A.phone_no, A.account_type, nvl(B.mtNo, 0) mt from ((select T1.service_code, decode(T1.account_type, '1', T1.super_account_no, T1.account_no) accNo, T1.phone_no, T1.account_type from t_service_order T1 inner join ( select /*+ parallel(T2,36) full(T2) */ distinct T2.super_account_no,T2.phone_no,T2.service_code, count(T2.super_account_no) cn from t_pkk_fail T2 group by T2.super_account_no,T2.phone_no,T2.service_code having count(T2.super_account_no) > 1 ) rs on (rs.super_account_no = T1.super_account_no and rs.phone_no = T1.phone_no and rs.service_code = T1.service_code and rs.cn > round((sysdate - add_months(T1.process_time, T1.free_month)) / 365) ) where province_code = '44' and add_months(process_time, free_month) < add_months(sysdate, -12) and charge_type = '2' )) A left join (select /*+ index(M,T_MT1_ACCOUNT_NO) */ account_no, count(account_no) mtNo from t_mail_info_mt1 M where province_code = '44' and account_no is not null and trade_date >= to_date('20160401','YYYYMMDD') and trade_date < to_date('20160501','YYYYMMDD') group by account_no) B on A.accno = B.account_no) X where X.mt = 0; ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 178 | | 424K (1)| 00:00:17 | | | | | | | 1 | SORT AGGREGATE | | 1 | 178 | | | | | | | | | | 2 | PX COORDINATOR | | | | | | | | | | | | | 3 | PX SEND QC (RANDOM) | :TQ10003 | 1 | 178 | | | | | | Q1,03 | P->S | QC (RAND) | | 4 | SORT AGGREGATE | | 1 | 178 | | | | | | Q1,03 | PCWP | | |* 5 | FILTER | | | | | | | | | Q1,03 | PCWC | | | 6 | NESTED LOOPS OUTER | | 1780 | 309K| | 424K (1)| 00:00:17 | | | Q1,03 | PCWP | | |* 7 | HASH JOIN | | 1780 | 283K| | 423K (1)| 00:00:17 | | | Q1,03 | PCWP | | | 8 | BUFFER SORT | | | | | | | | | Q1,03 | PCWC | | | 9 | PX RECEIVE | | 633K| 57M| | 184K (1)| 00:00:08 | | | Q1,03 | PCWP | | | 10 | PX SEND HYBRID HASH | :TQ10000 | 633K| 57M| | 184K (1)| 00:00:08 | | | | S->P | HYBRID HASH| | 11 | STATISTICS COLLECTOR | | | | | | | | | | | | | 12 | PARTITION LIST SINGLE | | 633K| 57M| | 184K (1)| 00:00:08 | 19 | 19 | | | | |* 13 | TABLE ACCESS FULL | T_SERVICE_ORDER | 633K| 57M| | 184K (1)| 00:00:08 | 19 | 19 | | | | | 14 | PX RECEIVE | | 18M| 1163M| | 238K (1)| 00:00:10 | | | Q1,03 | PCWP | | | 15 | PX SEND HYBRID HASH | :TQ10002 | 18M| 1163M| | 238K (1)| 00:00:10 | | | Q1,02 | P->P | HYBRID HASH| | 16 | VIEW | | 18M| 1163M| | 238K (1)| 00:00:10 | | | Q1,02 | PCWP | | |* 17 | FILTER | | | | | | | | | Q1,02 | PCWC | | | 18 | HASH GROUP BY | | 18M| 816M| 20G| 238K (1)| 00:00:10 | | | Q1,02 | PCWP | | | 19 | PX RECEIVE | | 18M| 816M| | 238K (1)| 00:00:10 | | | Q1,02 | PCWP | | | 20 | PX SEND HASH | :TQ10001 | 18M| 816M| | 238K (1)| 00:00:10 | | | Q1,01 | P->P | HASH | | 21 | HASH GROUP BY | | 18M| 816M| 20G| 238K (1)| 00:00:10 | | | Q1,01 | PCWP | | | 22 | PX BLOCK ITERATOR | | 364M| 15G| | 119K (1)| 00:00:05 | 1 | 35 | Q1,01 | PCWC | | | 23 | TABLE ACCESS FULL | T_PKK_FAIL | 364M| 15G| | 119K (1)| 00:00:05 | 1 | 35 | Q1,01 | PCWP | | | 24 | VIEW PUSHED PREDICATE | | 1 | 15 | | 22 (0)| 00:00:01 | | | Q1,03 | PCWP | | | 25 | SORT GROUP BY | | 1 | 42 | | 22 (0)| 00:00:01 | | | Q1,03 | PCWP | | | 26 | PARTITION RANGE ITERATOR | | 1 | 42 | | 22 (0)| 00:00:01 | 4 | 6 | Q1,03 | PCWP | | | 27 | PARTITION LIST SINGLE | | 1 | 42 | | 22 (0)| 00:00:01 | 19 | 19 | Q1,03 | PCWP | | | 28 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T_MAIL_INFO_MT1 | 1 | 42 | | 22 (0)| 00:00:01 | KEY | KEY | Q1,03 | PCWP | | |* 29 | INDEX RANGE SCAN | T_MT1_ACCOUNT_NO | 1 | | | 10 (0)| 00:00:01 | KEY | KEY | Q1,03 | PCWP | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - filter(NVL("B"."MTNO",0)=0) 7 - access("RS"."SUPER_ACCOUNT_NO"="T1"."SUPER_ACCOUNT_NO" AND "RS"."PHONE_NO"="T1"."PHONE_NO" AND "RS"."SERVICE_CODE"="T1"."SERVICE_CODE") filter("RS"."CN">ROUND((SYSDATE@!-ADD_MONTHS(INTERNAL_FUNCTION("T1"."PROCESS_TIME"),INTERNAL_FUNCTION("T1"."FREE_MONTH")))/365)) 13 - filter("T1"."CHARGE_TYPE"=2 AND ADD_MONTHS(INTERNAL_FUNCTION("T1"."PROCESS_TIME"),INTERNAL_FUNCTION("T1"."FREE_MONTH"))<ADD_MONTHS(SYSDATE@!,-12)) 17 - filter(COUNT(SYS_OP_CSR(SYS_OP_MSR(COUNT(*)),0))>1) 29 - access("ACCOUNT_NO"=DECODE("T1"."ACCOUNT_TYPE",'1',"T1"."SUPER_ACCOUNT_NO","T1"."ACCOUNT_NO")) Note ----- - dynamic statistics used: dynamic sampling (level=AUTO) - Degree of Parallelism is 36 because of table property 51 rows selected.
最终6分钟跑完了哈!
Oracle 12C 某电信公司 优化一个12小时跑不出来的SQL,最后6分钟就跑完了
标签:
原文地址:http://blog.csdn.net/yws_1990/article/details/51331919