概述
今天一个网友找我帮他优化他负责数据库的SQL,客服反映这个SQL 跑很久,跑了12个小时,最后跑出ORA-01555 ,以报错结束了这个慢SQL的生命。找我帮他优化,OK ,义不容辞。
他们那边数据库环境是Oracle 12C的:
原SQL 及其执行计划为:
<span style="font-size:10px;">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)</span>
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分钟就跑完了的全部内容,希望文章能够帮你解决Oracle 12C 某电信公司 优化一个12小时跑不出来的SQL,最后6分钟就跑完了所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复