Oracle 12C 某电信公司 优化一个12小时跑不出来的SQL,最后6分钟就跑完了

今天一个网友找我帮他优化他负责数据库的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(([email protected]!-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
	      ([email protected]!,-12))
  13 - filter(SYS_OP_BLOOM_FILTER(:BF0000,"ACCOUNT_NO"))
  14 - filter(COUNT(*)>ROUND(([email protected]!-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)

我改写的SQL 以及执行计划为:

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(([email protected]!-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([email protected]!,-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分钟跑完了哈!

时间: 2024-08-03 08:24:21

Oracle 12C 某电信公司 优化一个12小时跑不出来的SQL,最后6分钟就跑完了的相关文章

CenOS7 部署 数据库 Oracle 12c + 启动阶段与关闭状态 [12.2 企业版]

简介 1·Oracle 12c 特性2·Oracle 12c 服务器的硬件要求3·Oracle 12c 部署过程4·Oracle 12c 的启动方式与关闭状态5·Oracle 12c 的总结 Oracle 12c 特性 Oracle Database 12 c-是世界上第一个专为云设计的数据库. A·使用Oracle Multitenant插入云端 > 数据库整合是云之旅的关键一步.Oracle Database 12 c使流程更加快速和简单,实现了高密度的基于模式的整合 - 无需更改现有应用程

Centos 7下安装Oracle 12c 以及装后优化(附软件包)

Oracle 12c 数据库概述 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一.比如SilverStream就是基于数据库的一种中间件.ORACLE数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具有完整的数据管理功能:作为一个关系数据库,它是一个完备关系的产品:作为分布式数据库它实现了分布式处理功能.但它的所有知识,只要在一种机型上

Oracle数据库该如何着手优化一个SQL

这是个终极问题,因为优化本身的复杂性实在是难以总结的,很多时候优化的方法并不是用到了什么高深莫测的技术,而只是一个思想意识层面的差异,而这些都很可能连带导致性能表现上的巨大差异.所以有时候我们应该先搞清楚需求到底是什么,SQL本身是否合理,这些思考很可能会使优化工作事半功倍.而本文是假设SQL本身合理,从Oracle提供给我们的一些技术手段来简单介绍下Oracle数据库,该如何使用一些现有的技术来优化一个SQL执行的性能. 确定需要优化的SQL文本及当前SQL执行计划 确定SQL涉及的所有表及其

Oracle 12c 添加scott用户

对于熟悉Oracle或者接触过Oracle的人,scott这个用户大家一定相当的熟悉.12c推出了可插拔数据库,在一个容器cdb中以多租户的形式同时存在多个数据库pdb.pdb中默认不包含scott用户. 为了做数据泵的实验,需要一个测试用户,因此需要在pdb中添加scott用户. oracle 12c自带了scott的脚本,$ORACLE_HOME/rdbms/admin/utlsampl.sql 内容如下: Rem Copyright (c) 1990, 2006, Oracle. All

Oracle 12c创建用户是出现“ORA-65096: invalid common user or role name”的错误

这篇文章主要介绍CDB和PDB的基本管理,资料来源oracle官方. 基本概念: Multitenant Environment:多租户环境 CDB(Container Database):数据库容器 PD(Pluggable Database):可插拔数据库 CDB与PDB关系图 COMMON USERS(普通用户):经常建立在CDB层,用户名以C##或c##开头: LOCAL USERS(本地用户):仅建立在PDB层,建立的时候得指定CONTAINER. 在oracle 12c中,使用了一个

zabbix监控oracle 12c

zabbix监控oracle 12c 前言 某公司需要监控Oracle 12C,采用orabbix是zabbix监控oracle数据库的插件,修改一些地方就可以监控了. 一.安装配置 mkdir /opt/orabbix cd /opt/orabbix mv conf/config.props.sample conf/config.props cp init.d/orabbix /etc/init.d/ chmod +x /etc/init.d/orabbix chkconfig orabbix

Oracle 12c 安装及配置

Oracle 12c R2 for Windows_X64 安装 1.安装准备 1.1 下载Oracle for Windows版本 官方下载地址:http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 1.2 解压zip压缩包文件 解压下载的压缩包文件至同一目录中,目录中避免出现汉字和空格,如某目录下的database文件夹中,解压后的文件目录结构如下:  2.安装过程 2.1 执行安

12小时超级马拉松赛记

8月初再次来到印度Pune出差,还是在TWU当讲师.这次的TWU是第51期,也是有史以来人数最多的一期.整个TWU的工作很多,非常忙,经常从早上8点忙到晚上8点.为了备战10月份的越野比赛,只有在周末才有时间拉个半马. 9月初从www.townscirpt.com网站上看到9月24日Pune会举行一场12小时超级马拉松,从晚上的7点钟跑到第二天早上的7点钟,心里顿时长了草.自己之前还没有参加过12小时超级马拉松,所以很想得到这样的一份体验.另外可以把这场比赛作为10月份越野赛的很好的一次赛前拉练

Oracle 12c 12.1.0.1.0管理控制文件官方文档翻译说明

Link: http://download.csdn.net/detail/rlhua/7718571 官方Link: http://docs.oracle.com/database/121/ADMIN/control.htm#ADMIN006 版本: [email protected]>select * from v$version; BANNER