Steps to generate good plan from nonPROD to PROD

PT Issue: step by step Doc to generate good plan from nonPROD to PROD.

Issue in detail:

  • Query Performance of Hyperion application monthly batch job in PROD is very slow and not moving further after 10 hours. As per Application team Normal execution time is below 15 minutes and No code changes happened. Application team uses Oracle Data Integrator to schedule the batch jobs.
  • Application team informed that the same data volume is present in PROD and non-PROD and queries are running very fast in non-PROD.
  • Five queries had been found in PROD with slow performance.
  • In the non-prod the same queries executed in 5 to 10 minutes, but in the prod, query had been running for 10 hours.
  • Verified that the stats have been gathered on all schemas and found that the plan hash value is different in PROD Vs non-PROD environments even though the data volume is same in both PROD and non-PROD.
  • It had been found problematic SQL_IDs and  then created profiles in the non-PROD and then applied in the PROD one after the other query.
  • Doc ID 1487302.1 followed to resolve the issue.

       –> Using Sqltxplain to create a ‘SQL Profile’ to consistently reproduce a good plan (Doc ID 1487302.1)

 

Steps followed to resolve issue:

 

1) On both PROD and nonPROD

Download sqltxplain utility from

SQLT (SQLTXPLAIN) – Tool that helps to diagnose a SQL statement performing poorly (Doc ID 215187.1)

The script named coe_xfr_sql_profile.sql is provided under the sqlt/utl directory.

Unzip sqlt.zip on both databases.

 

 

2) On Non PROD

Find the sql_id and the plan_hash_value (if there is more than one plan) for the statement that you want to create the profile against.

             To get SQL_ID è  select sql_id from v$session where sid=<SID>;

Having the sql_id, we can obtain the “plan_hash_value” running the statement below. Note that if there is more than one plan for the same sql, it will show multiples. And based on latest SNAP_ID(AWR) take the current PLAN_HASH_VALUE

            To get the plan_hash_valueè

SQL> set lines 100 pages 100;

SQL> col plan_hash_value format 999999999999;

SQL> col elapse_us format 999999999999999999;

SQL> col buffer_gets_total format 999999999999999999;

SQL> select snap_id, plan_hash_value, executions_total, elapsed_time_total elapse_us, buffer_gets_total

2  from dba_hist_sqlstat

3  where sql_id=’4tvpf2r4p5747′

4  and snap_id in(select snap_id from dba_hist_snapshot where begin_interval_time>=sysdate -6);

 

Output of above Query:

SNAP_ID PLAN_HASH_VALUE EXECUTIONS_TOTAL           ELAPSE_US   BUFFER_GETS_TOTAL

———- ————— —————- ——————- ——————-

19356      3296833727                1                                                       113652024             1466917

 

                                    OR

WITH
p AS (
SELECT plan_hash_value
FROM gv$sql_plan
WHERE sql_id = TRIM(‘&&sql_id.’)
AND other_xml IS NOT NULL
UNION
SELECT plan_hash_value
FROM dba_hist_sql_plan
WHERE sql_id = TRIM(‘&&sql_id.’)
AND other_xml IS NOT NULL ),
m AS (
SELECT plan_hash_value,
SUM(elapsed_time)/SUM(executions) avg_et_secs
FROM gv$sql
WHERE sql_id = TRIM(‘&&sql_id.’)
AND executions > 0
GROUP BY
plan_hash_value ),
a AS (
SELECT plan_hash_value,
SUM(elapsed_time_total)/SUM(executions_total) avg_et_secs
FROM dba_hist_sqlstat
WHERE sql_id = TRIM(‘&&sql_id.’)
AND executions_total > 0
GROUP BY
plan_hash_value )
SELECT p.plan_hash_value,
ROUND(NVL(m.avg_et_secs, a.avg_et_secs)/1e6, 3) avg_et_secs
FROM p, m, a
WHERE p.plan_hash_value = m.plan_hash_value(+)
AND p.plan_hash_value = a.plan_hash_value(+)
ORDER BY
avg_et_secs NULLS LAST;

Output for the above query:

Enter value for sql_id: 4tvpf2r4p5747

PLAN_HASH_VALUE AVG_ET_SECS

————— ———–

3296833727        .089

 

3) ON Non PROD

Having the sql_id and the plan_hash_id, run the following:

sqlplus / as sysdba

SQL> START coe_xfr_sql_profile.sql [SQL_ID] [PLAN_HASH_VALUE];

start coe_xfr_sql_profile.sql  4tvpf2r4p5747 3296833727

This will generate a script named like:

coe_xfr_sql_profile_&&sql_id._&&plan_hash_value..sql

 

For example:

coe_xfr_sql_profile_4tvpf2r4p5747_3296833727.sql

 

This file contains the stored profile from the database that you obtained it from.  You can now use this script to apply the same plan to another database:

SQL> START coe_xfr_sql_profile.sql 4tvpf2r4p5747 3296833727

Parameter 1:

SQL_ID (required)

PLAN_HASH_VALUE AVG_ET_SECS

————— ———–

3296833727     112.573

Parameter 2:

PLAN_HASH_VALUE (required)

 

Values passed to coe_xfr_sql_profile:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SQL_ID         : “4tvpf2r4p5747”

PLAN_HASH_VALUE: “3296833727”

 

SQL>BEGIN

2    IF :sql_text IS NULL THEN

3      RAISE_APPLICATION_ERROR(-20100, ‘SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).’);

4    END IF;

5  END;

6  /

SQL>SET TERM OFF;

Execute coe_xfr_sql_profile_4tvpf2r4p5747_3296833727.sql
on TARGET system in order to create a custom SQL Profile
with plan 3296833727 linked to adjusted sql_text.

COE_XFR_SQL_PROFILE completed.

 

Profiles that were generated for PROD env from non- PROD shown below in the screen shot.

 

In non production:

coe_xfr_sql_profile_4tvpf2r4p5747_3296833727.sql
coe_xfr_sql_profile_gbgahmaan5w7u_3956090555.sql
coe_xfr_sql_profile_3pwx7b1v2s8wg_3763355411.sql
coe_xfr_sql_profile_6ux6hwwqjw83y_4208858076.sql
coe_xfr_sql_profile_5kprm78jk2da0_2871340315.sql

 

4) ON PROD

Just execute this script in the DB where you want to create this profile

 

Copy from NONPROD to PROD

 

sqlplus / as sysdba

SQL> START coe_xfr_sql_profile_4tvpf2r4p5747_3296833727.sql

 

PROD Database:

coe_xfr_sql_profile_4tvpf2r4p5747_3296833727.sql
coe_xfr_sql_profile_4tvpf2r4p5747_3296833727.log
coe_xfr_sql_profile_gbgahmaan5w7u_3956090555.sql
coe_xfr_sql_profile_gbgahmaan5w7u_3956090555.log
coe_xfr_sql_profile_3pwx7b1v2s8wg_3763355411.sql
coe_xfr_sql_profile_3pwx7b1v2s8wg_3763355411.log
coe_xfr_sql_profile_6ux6hwwqjw83y_4208858076.sql
coe_xfr_sql_profile_6ux6hwwqjw83y_4208858076.log
coe_xfr_sql_profile_5kprm78jk2da0_2871340315.sql
coe_xfr_sql_profile_5kprm78jk2da0_2871340315.log

Note:

After creation of SQL profiles in PROD with good plan from non prod ,Each and every Querys’ execution completed in less than 10 mins separately.

 

See Also: