Problem
One of our customer started facing lot of performance issues with data loads after upgrading database to 11.2.0.1.
It was one of the classic performance issues and customer complained that it was working fine in past and after 11g upgrade it is slow.
Troubleshooting
Let’s start by troubleshooting data loads as it was lagging by 30 days since database was upgraded to 11g.
Code:
INSERT
/*+ PARALLEL (d, 8 ) APPEND NOLOGGING */
INTO HAJI.OPPS_PART_A_DATA D
(
HOSP_ID,
RUN_DT,
LINK_NUM,
HSE_CLM_THRU_DT,
HSE_CLM_STUS_CD,
FINL_ACTN_SW,
BENE_DOB,
BENE_AGE,
DGNS_CD,
SQNC_NUM,
HCPCS_CD,
HSE_CLM_FROM_DT
)
SELECT FA.PROVDR_NUM AS HOSP_ID,
RCC.RUN_DT AS RUN_DT,
RCC.PTA_LINK_NUM AS LINK_NUM,
RCC.CLM_THRU_DT AS HSE_CLM_THRU_DT,
DE.PTNT_DSCHRG_STUS_CD AS HSE_CLM_STUS_CD,
'Y' AS FINL_ACTN_SW,
A.BENE_DOB,
A.BENE_AGE,
NULL AS DGNS_CD,
NULL AS SQNC_NUM,
HB.HCPCS_CD AS HCPCS_CD,
FA.CLM_FROM_DT
FROM PART_A.PART_A_RCC_FACT RCC,
PART_A.PART_A_FACT FA,
PART_B.HCPCS_DIMENSION HB,
PART_A.PART_A_DEMOG_DIMENSION DE,
HAJI.OPPS_HAJI_CLM_A_5 A,
PART_A.PTA_BENE_AT_TIME_CLM B
WHERE RCC.HCPCS_ID = HB.HCPCS_ID
AND RCC.RUN_DT = FA.RUN_DT
AND RCC.PTA_LINK_NUM = FA.PTA_LINK_NUM
AND FA.PART_A_DEMOG_ID = DE.PART_A_DEMOG_ID
AND FA.NOT_FINAL_ID = 1
AND FA.CLM_FROM_DT BETWEEN :B2 AND :B1
AND HB.HCPCS_CD IS NOT NULL
AND RCC.RUN_DT = A.RUN_DT
AND RCC.PTA_LINK_NUM = A.LINK_NUM
AND FA.PTA_BENE_AT_TIME_CLM_ID = B.PTA_BENE_AT_TIME_CLM_ID
AND B.BENE_CLM_NUM = A.BENE_CLM_NUM
One obvious thing is that parallel hint in SQL is missing but lets look at AWR statistics.
SQL> @awr_plan_stats.sql
Enter value for sql_id: dxh8ua3m4r1cm
old 19: where s.sql_id = '&&sql_id'
new 19: where s.sql_id = 'dxh8ua3m4r1cm'
SQL_ID PLAN_HASH_VALUE TIMESTAMP COST EXECS ETIME AVG_ETIME AVG_CPU_TIME AVG_LIO AVG_PIO
------------- --------------- ---------- ---------- ------------ -------------- ------------ ------------ ------------------ ----------------
dxh8ua3m4r1cm 3805054770 05/20/2010 1856142 7 797,194.0 113,885.000 94,881.000 765,562,270.0 155,392,524.0
dxh8ua3m4r1cm 186961658 08/26/2010 23659798 1 230,488.0 230,488.000 156,687.000 1,838,600,713.0 489,677,147.0
dxh8ua3m4r1cm 3349766997 10/16/2010 6857347 -1 926,089.0 926,089.000 685,247.000 5,789,878,135.0 294,945,596.0
dxh8ua3m4r1cm 2612482448 10/21/2010 2012203 -1 117,218.0 117,218.000 30,378.000 502,440,465.0 129,779,745.0
old 2: where sql_id='&&sql_id' order by timestamp
new 2: where sql_id='dxh8ua3m4r1cm' order by timestamp
SQL_ID PLAN_HASH_VALUE TIMESTAMP
------------- --------------- ----------
dxh8ua3m4r1cm 3805054770 05/20/2010
dxh8ua3m4r1cm 186961658 08/26/2010
dxh8ua3m4r1cm 3349766997 10/16/2010
dxh8ua3m4r1cm 2612482448 10/21/2010
7 rows selected.
SQL> @getplan_awr
Please enter the sql_id :dxh8ua3m4r1cm
Please enter the plan_hash_value :3349766997
Please enter the format typical or advanced :typical
old 1: SELECT * FROM TABLE(dbms_xplan.display_awr('&sql_id','&plan_hash_value',NULL,'&format1'))
new 1: SELECT * FROM TABLE(dbms_xplan.display_awr('dxh8ua3m4r1cm','3349766997',NULL,'typical'))
..
Plan hash value: 3349766997
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | | | | 6857K(100)| | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | | | | | | | | Q1,01 | P->S | QC (RAND) |
| 3 | LOAD AS SELECT | | | | | | | | | Q1,01 | PCWP | |
| 4 | FILTER | | | | | | | | | Q1,01 | PCWC | |
| 5 | NESTED LOOPS | | | | | | | | | Q1,01 | PCWP | |
| 6 | NESTED LOOPS | | 1 | 152 | | 6857K (1)| 26:40:03 | | | Q1,01 | PCWP | |
| 7 | NESTED LOOPS | | 1 | 139 | | 6857K (1)| 26:40:03 | | | Q1,01 | PCWP | |
| 8 | NESTED LOOPS | | 1 | 132 | | 6857K (1)| 26:40:03 | | | Q1,01 | PCWP | |
| 9 | BUFFER SORT | | | | | | | | | Q1,01 | PCWC | |
| 10 | PX RECEIVE | | | | | | | | | Q1,01 | PCWP | |
| 11 | PX SEND BROADCAST | :TQ10000 | | | | | | | | | S->P | BROADCAST |
| 12 | HASH JOIN | | 38773 | 3900K| 5840K| 2060K (3)| 08:00:53 | | | | | |
| 13 | NESTED LOOPS | | | | | | | | | | | |
| 14 | NESTED LOOPS | | 78486 | 4905K| | 1925K (3)| 07:29:19 | | | | | |
| 15 | PARTITION RANGE ALL | | 74063 | 3254K| | 1881K (3)| 07:18:57 | 1 | 105 | | | |
| 16 | PARTITION LIST ALL | | 74063 | 3254K| | 1881K (3)| 07:18:57 | 1 | LAST | | | |
| 17 | TABLE ACCESS FULL | PART_A_FACT | 74063 | 3254K| | 1881K (3)| 07:18:57 | 1 | 14999 | | | |
| 18 | INDEX UNIQUE SCAN | PK_PTA_BENE_AT_TIME | 1 | | | 1 (0)| 00:00:01 | | | | | |
| 19 | TABLE ACCESS BY INDEX ROWID | PTA_BENE_AT_TIME_CLM | 1 | 19 | | 1 (0)| 00:00:01 | | | | | |
| 20 | TABLE ACCESS FULL | OPPS_HAJI_CLM_A_5 | 38M| 1428M| | 54822 (2)| 00:12:48 | | | | | |
| 21 | PX PARTITION LIST AND | | 1 | 29 | | 124 (0)| 00:00:02 |KEY(AP)|KEY(AP)| Q1,01 | PCWC | |
| 22 | TABLE ACCESS BY LOCAL INDEX ROWID| PART_A_RCC_FACT | 1 | 29 | | 124 (0)| 00:00:02 | KEY | KEY | Q1,01 | PCWP | |
| 23 | INDEX RANGE SCAN | IDX_PARCCF_PTA_LINK_NUM | 1 | | | 123 (0)| 00:00:02 | KEY | KEY | Q1,01 | PCWP | |
| 24 | TABLE ACCESS BY INDEX ROWID | PART_A_DEMOG_DIMENSION | 1 | 7 | | 1 (0)| 00:00:01 | | | Q1,01 | PCWP | |
| 25 | INDEX UNIQUE SCAN | PK_PADD_PTA_DEMOG_ID | 1 | | | 1 (0)| 00:00:01 | | | Q1,01 | PCWP | |
| 26 | INDEX UNIQUE SCAN | PK_HCPCSD_ID | 1 | | | 1 (0)| 00:00:01 | | | Q1,01 | PCWP | |
| 27 | TABLE ACCESS BY INDEX ROWID | HCPCS_DIMENSION | 1 | 13 | | 1 (0)| 00:00:01 | | | Q1,01 | PCWP | |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=6)
59 rows selected.
SQL>
61 rows selected.
SQL> @getplan_awr
Please enter the sql_id :dxh8ua3m4r1cm
Please enter the plan_hash_value :3805054770
Please enter the format typical or advanced :typical
old 1: SELECT * FROM TABLE(dbms_xplan.display_awr('&sql_id','&plan_hash_value',NULL,'&format1'))
new 1: SELECT * FROM TABLE(dbms_xplan.display_awr('dxh8ua3m4r1cm','3805054770',NULL,'typical'))
...
Plan hash value: 3805054770
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | | | 1856K(100)| | | | | | |
| 1 | LOAD AS SELECT | | | | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10003 | 1 | 151 | 1856K (13)| 07:13:06 | | | Q1,03 | P->S | QC (RAND) |
| 4 | FILTER | | | | | | | | Q1,03 | PCWC | |
| 5 | NESTED LOOPS | | 1 | 151 | 1856K (13)| 07:13:06 | | | Q1,03 | PCWP | |
| 6 | NESTED LOOPS | | 1 | 139 | 1856K (13)| 07:13:06 | | | Q1,03 | PCWP | |
| 7 | NESTED LOOPS | | 1 | 132 | 1856K (13)| 07:13:06 | | | Q1,03 | PCWP | |
| 8 | HASH JOIN | | 5197 | 573K| 1853K (13)| 07:12:23 | | | Q1,03 | PCWP | |
| 9 | HASH JOIN | | 716K| 50M| 1811K (14)| 07:02:36 | | | Q1,03 | PCWP | |
| 10 | PX RECEIVE | | 636K| 27M| 77813 (1)| 00:18:10 | | | Q1,03 | PCWP | |
| 11 | PX SEND HASH | :TQ10002 | 636K| 27M| 77813 (1)| 00:18:10 | | | Q1,02 | P->P | HASH |
| 12 | PX PARTITION LIST ALL | | 636K| 27M| 77813 (1)| 00:18:10 | 1 | LAST | Q1,02 | PCWC | |
| 13 | TABLE ACCESS BY LOCAL INDEX ROWID| PART_A_FACT | 636K| 27M| 77813 (1)| 00:18:10 | 1 | 11877 | Q1,02 | PCWP | |
| 14 | INDEX RANGE SCAN | IDX_PAF_CLM_FROM_DT | 770K| | 438 (3)| 00:00:07 | 1 | 11877 | Q1,02 | PCWP | |
| 15 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 16 | PX RECEIVE | | 4010M| 108G| 1684K (12)| 06:33:00 | | | Q1,03 | PCWP | |
| 17 | PX SEND HASH | :TQ10000 | 4010M| 108G| 1684K (12)| 06:33:00 | | | | S->P | HASH |
| 18 | PARTITION RANGE ALL | | 4010M| 108G| 1684K (12)| 06:33:00 | 1 | 100 | | | |
| 19 | PARTITION LIST ALL | | 4010M| 108G| 1684K (12)| 06:33:00 | 1 | LAST | | | |
| 20 | TABLE ACCESS FULL | PART_A_RCC_FACT | 4010M| 108G| 1684K (12)| 06:33:00 | 1 | 2821 | | | |
| 21 | BUFFER SORT | | | | | | | | Q1,03 | PCWC | |
| 22 | PX RECEIVE | | 25M| 961M| 41561 (3)| 00:09:42 | | | Q1,03 | PCWP | |
| 23 | PX SEND HASH | :TQ10001 | 25M| 961M| 41561 (3)| 00:09:42 | | | | S->P | HASH |
| 24 | TABLE ACCESS FULL | OPPS_HAJI_CLM_A_5 | 25M| 961M| 41561 (3)| 00:09:42 | | | | | |
| 25 | TABLE ACCESS BY INDEX ROWID | PTA_BENE_AT_TIME_CLM | 1 | 19 | 1 (0)| 00:00:01 | | | Q1,03 | PCWP | |
| 26 | INDEX UNIQUE SCAN | PK_PTA_BENE_AT_TIME | 1 | | 1 (0)| 00:00:01 | | | Q1,03 | PCWP | |
| 27 | TABLE ACCESS BY INDEX ROWID | PART_A_DEMOG_DIMENSION | 1 | 7 | 1 (0)| 00:00:01 | | | Q1,03 | PCWP | |
| 28 | INDEX UNIQUE SCAN | PK_PADD_PTA_DEMOG_ID | 1 | | 1 (0)| 00:00:01 | | | Q1,03 | PCWP | |
| 29 | TABLE ACCESS BY INDEX ROWID | HCPCS_DIMENSION | 1 | 12 | 1 (0)| 00:00:01 | | | Q1,03 | PCWP | |
| 30 | INDEX UNIQUE SCAN | PK_HCPCSD_ID | 1 | | 1 (0)| 00:00:01 | | | Q1,03 | PCWP | |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
58 rows selected.
EXEC = -1 means DATA LOAD was started but killed as it was taking more time. As you can see from above window that load took 113,885 seconds compared to that of 926,089 and 117,218seconds and was eventually stopped. I have modified Kerry Osborne’s script awr_plan_stats.sql to show timestamp. ETL team confimred that load ran in acceptable timeframe on 05/20/2010.
Solution
Modify code
I modified SQL code to simulate plan of hash_value 3805054770 when load ran fine. Production support modified ETL package and load completed in 57,600 seconds. I couldn’t do explain plan on INSERT as being Developer DBA I did not have write access to table.
SQL> explain plan for
2 select /*+ full(rcc) full (a) PARALLEL (rcc,8) */ fa.provdr_num as HOSP_ID,
3 rcc.RUN_DT as RUN_DT,
4 rcc.pta_link_num as LINK_NUM,
5 rcc.clm_thru_dt AS HSE_CLM_THRU_DT,
6 De.ptnt_dschrg_stus_cd as HSE_CLM_STUS_CD,
7 'Y' as finl_actn_sw,
8 a.bene_dob,
9 a.bene_age,
10 NULL AS dgns_cd,
11 NULL AS sqnc_num,
12 hb.hcpcs_cd as HCPCS_CD,
13 fa.clm_from_dt
14 from part_a.part_a_demog_dimension de,
15 part_b.hcpcs_dimension hb,
16 haji.opps_haji_clm_a_5 a,
17 part_a.pta_bene_at_time_clm b,
18 part_a.part_a_rcc_fact rcc,
19 part_a.part_a_fact fa
20 where rcc.hcpcs_id = hb.hcpcs_id
21 and rcc.run_dt = fa.run_dt
22 and rcc.pta_link_num = fa.pta_link_num
23 and fa.part_a_demog_id = de.part_a_demog_id
24 and fa.not_final_id = 1
25 and fa.clm_from_dt BETWEEN :v_start_date AND :v_end_date
26 and hb.hcpcs_cd is not null
27 and rcc.run_dt = a.run_dt
28 and rcc.pta_link_num = a.link_num
29 and fa.pta_bene_at_time_clm_id = b.pta_bene_at_time_clm_id
30 and b.bene_clm_num = a.bene_clm_num;
Explained.
--------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 152 | 458K (6)| 01:46:56 | | |
|* 1 | PX COORDINATOR | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10005 | | | | | | |
|* 3 | FILTER | | | | | | | |
| 4 | NESTED LOOPS | | | | | | | |
| 5 | NESTED LOOPS | | 1 | 152 | 458K (6)| 01:46:56 | | |
| 6 | NESTED LOOPS | | 1 | 139 | 458K (6)| 01:46:56 | | |
|* 7 | HASH JOIN | | 1 | 132 | 458K (6)| 01:46:56 | | |
| 8 | PX RECEIVE | | 13752 | 1517K| 411K (6)| 01:36:02 | | |
| 9 | PX SEND HASH | :TQ10004 | 13752 | 1517K| 411K (6)| 01:36:02 | | |
|* 10 | HASH JOIN | | 13752 | 1517K| 411K (6)| 01:36:02 | | |
| 11 | PX RECEIVE | | 1990K| 140M| 356K (6)| 01:23:14 | | |
| 12 | PX SEND HASH | :TQ10003 | 1990K| 140M| 356K (6)| 01:23:14 | | |
|* 13 | HASH JOIN | | 1990K| 140M| 356K (6)| 01:23:14 | | |
| 14 | PX RECEIVE | | 1990K| 85M| 88870 (1)| 00:20:45 | | |
| 15 | PX SEND BROADCAST | :TQ10002 | 1990K| 85M| 88870 (1)| 00:20:45 | | |
| 16 | PX PARTITION LIST ALL | | 1990K| 85M| 88870 (1)| 00:20:45 | 1 | LAST |
| 17 | TABLE ACCESS BY LOCAL INDEX ROWID| PART_A_FACT | 1990K| 85M| 88870 (1)| 00:20:45 | 1 | 14999 |
|* 18 | INDEX RANGE SCAN | IDX_PAF_NF_ID_CLM_DT | 3643K| | 2726 (1)| 00:00:39 | 1 | 14999 |
| 19 | PX BLOCK ITERATOR | | 5775M| 155G| 263K (7)| 01:01:32 | 1 | LAST |
| 20 | TABLE ACCESS FULL | PART_A_RCC_FACT | 5775M| 155G| 263K (7)| 01:01:32 | 1 | 3559 |
| 21 | BUFFER SORT | | | | | | | |
| 22 | PX RECEIVE | | 38M| 1428M| 54823 (2)| 00:12:48 | | |
| 23 | PX SEND HASH | :TQ10000 | 38M| 1428M| 54823 (2)| 00:12:48 | | |
| 24 | TABLE ACCESS FULL | OPPS_HAJI_CLM_A_5 | 38M| 1428M| 54823 (2)| 00:12:48 | | |
| 25 | BUFFER SORT | | | | | | | |
| 26 | PX RECEIVE | | 77M| 1408M| 46623 (2)| 00:10:53 | | |
| 27 | PX SEND HASH | :TQ10001 | 77M| 1408M| 46623 (2)| 00:10:53 | | |
| 28 | TABLE ACCESS FULL | PTA_BENE_AT_TIME_CLM | 77M| 1408M| 46623 (2)| 00:10:53 | | |
| 29 | TABLE ACCESS BY INDEX ROWID | PART_A_DEMOG_DIMENSION | 1 | 7 | 0 (0)| 00:00:01 | | |
|* 30 | INDEX UNIQUE SCAN | PK_PADD_PTA_DEMOG_ID | 1 | | 0 (0)| 00:00:01 | | |
|* 31 | INDEX UNIQUE SCAN | PK_HCPCSD_ID | 1 | | 0 (0)| 00:00:01 | | |
|* 32 | TABLE ACCESS BY INDEX ROWID | HCPCS_DIMENSION | 1 | 13 | 0 (0)| 00:00:01 | | |
--------------------------------------------------------------------------------------------------------------------------------------------
Make it work without changing the code
Create SQL Tuning set using good plan from AWR and load plan in to SQL plan baseline. I did not had luxury to run this fully due to limited access. Last SQL statement will vouch that plan is loaded into SPM.
vdesai@HADWPR01> EXEC DBMS_SQLTUNE.CREATE_SQLSET('LOAD_PARTA','SYS');
PL/SQL PROCEDURE successfully completed.
vdesai@HADWPR01>
DECLARE
baseline_ref_cursor DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
OPEN baseline_ref_cursor FOR SELECT VALUE(p) FROM TABLE(DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY(31703, 38262, 6 'sql_id=' ||CHR(39) ||'dxh8ua3m4r1cm' ||CHR(39) ||' and plan_hash_value=3805054770',NULL,NULL,NULL, NULL,NULL,NULL,'ALL')) p;
DBMS_SQLTUNE.LOAD_SQLSET('LOAD_PARTA', baseline_ref_cursor);
END;
/
PL/SQL PROCEDURE successfully completed.
SELECT sqlset_name, sql_id,plan_hash_value 2 FROM dba_sqlset_statements;
SQLSET_NAME SQL_ID PLAN_HASH_VALUE
------------------------------ ------------- ---------------
LOAD_PARTA dxh8ua3m4r1cm 3805054770
1 row selected.
EXEC DBMS_SPM.LOAD_PLANS_FROM_SQLSET ( sqlset_name =>'LOAD_PARTA', sqlset_owner =>'VDESAI', fixed=>'YES', enabled=>'YES');
SELECT * FROM dba_sql_plan_baselines;