Les mises à jour R12.1/R12.2 sont assez volumineuses et prennent du temps. Nous devons trouver tous les SQL de longue durée afin de résoudre les problèmes de performances de la mise à niveau R12.2. Comme chaque itération prend beaucoup de temps, c'est important, nous avons essayé de trouver les problèmes de performances en moins d'itérations et de les corriger en conséquence
Voici les principales requêtes AWR utiles pour résoudre les problèmes de performances de la mise à niveau R12.2
Si SQL est toujours en mémoire (cache de curseur), les éléments suivants peuvent être utilisés pour identifier les SQL de longue durée qui n'ont peut-être pas encore été écrits dans l'AWR (au dernier instantané)
SELECT * FROM (SELECT ss.sql_id, ROUND(SUM(ss.elapsed_time/1000000),0) elapsed_time_secs, ROUND(SUM(ss.cpu_time/1000000),0) cpu_time_secs, SUM(ss.disk_reads) disk_reads, SUM(ss.direct_writes) direct_writes, SUM(ss.buffer_gets) buffer_gets, SUM(ss.px_servers_executions) px_server_execs, SUM(ss.rows_processed) rows_processed, SUM(ss.executions) executions, SUM(ss.application_wait_time) apwait_secs, SUM(ss.sharable_mem) sharable_mem, SUM(ss.total_sharable_mem) total_sharable_mem FROM v$sqlstats ss GROUP BY ss.sql_id ORDER BY 2 DESC) WHERE ROWNUM <= 100;
Le script SQL suivant signalera le SQL le plus long entre deux instantanés AWR
SELECT * FROM (SELECT dhs.sql_id, ROUND(SUM(dhs.elapsed_time_delta/1000000),0) elapsed_time_secs, ROUND(SUM(dhs.cpu_time_delta/1000000),0) cpu_time_secs, SUM(dhs.disk_reads_delta) disk_reads, SUM(dhs.buffer_gets_delta) buffer_gets, SUM(dhs.px_servers_execs_delta) px_server_execs, SUM(dhs.rows_processed_delta) rows_processed, SUM(dhs.executions_delta) executions, ROUND(SUM(dhs.iowait_delta/1000000),0) iowait_secs, ROUND(SUM(dhs.clwait_delta/1000000),0) clwait_secs, ROUND(SUM(dhs.ccwait_delta/1000000),0) ccwait_secs, ROUND(SUM(dhs.apwait_delta/1000000),0) apwait_secs FROM dba_hist_sqlstat dhs ,v$database d WHERE dhs.dbid = d.dbid AND snap_id > &begin_snap and snap_id <= &end_snap GROUP BY dhs.sql_id ORDER BY 2 DESC) WHERE ROWNUM <= 100;
Où &begin_snap et &end_snap sont les ID d'instantané de début et de fin.
Le résultat de cette instruction ressemblera à ce qui suit :
SQL_ID ELAPSED_TIME_SECS CPU_TIME_SECS DISK_READS BUFFER_GETS…. ------------- ----------------- --------------- ---------- ----------- …. 5vaxut40xbrmr 367440 42999 34838244 3795838289 …. 943ra4b7zg28x 264369 170788 441127 562033013 …. fkkrk9frwqfdr 70370 6448 3599284 469639133 …. 4847s6dt6sds9 68298 38896 7125573 1327384554 …. 2k3uw8n473r30 63600 27402 20043712 587615960 ….
Remarque :Le temps écoulé est le temps écoulé maximum pour tous les travailleurs d'un travail.
Enterprise Manager peut également être utilisé pour identifier les SQL coûteux au fur et à mesure qu'ils se produisent.
Obtenir le rapport de curseur d'affichage pour SQL de longue durée
Pour cela STATISTICS_LEVEL=ALL et _rowsource_execution_statistics =TRUE. Il doit être exécuté sans délai pour obtenir toutes les informations, sinon ces informations seront supprimées de SGA
SET pages 0 SET lines 300 SET LONG 10000 SET LONGCHUNKSIZE 10000 SPOOL <report>.txt SELECT * FROM TABLE(dbms_xplan.display_cursor('<SQL ID>', NULL, 'ALL +ALLSTATS')); SPOOL OFF;
Si le SQL n'est plus en mémoire, mais dans l'AWR, utilisez plutôt le rapport Display AWR :
SET pages 0 SET lines 300 SET LONG 10000 SET LONGCHUNKSIZE 10000 SPOOL .txt SELECT * FROM TABLE(dbms_xplan.display_awr('<SQL ID>', NULL, NULL, 'ALL')); SPOOL OFF;
Remarque :sachez que le rapport Display AWR (DBMS_XPLAN.DISPLAY_AWR) ne rapporte pas les valeurs réelles :il n'a pas d'option +ALLSTATS et il n'y a pas de statistiques réelles pour les étapes du plan d'exécution stockées dans AWR
Remarque importante :le curseur d'affichage et les rapports AWR n'affichent que le sql_text (1 000 premiers caractères) et non le sql_fulltext. Donc, si nécessaire, exécutez le script SQL suivant pour obtenir le texte SQL complet
SET pages 0 SET lines 300 SET LONG 10000 SET LONGCHUNKSIZE 10000 SPOOL<report_name>.txt SELECT sql_id, sql_text, sql_fulltext FROM v$SQL WHERE sql_id = '<sql_id>'; SPOOL OFF;
Obtenir le rapport SQL Monitor pour SQL à l'aide de la requête parallèle/DML
Le principal avantage de ceci est qu'il donne une bonne vue de la façon dont le SQL/DML parallèle fonctionne à travers les étapes du plan et des esclaves parallèles
set trimspool on set trim on set pages 0 set long 10000000 set long chunksize 10000000 set linesize 200 set termout off spool sql_monitor_for_<sql_id>.htm variable my_rept CLOB; BEGIN :my_rept := dbms_sqltune.report_sql_monitor(sql_id => '<sql_id>', report_level => 'ALL', type => 'HTML'); END; / print :my_rept spool off; set termout on
Où &begin_snap et &end_snap et sont les ID d'instantané de début et de fin.
Comment savoir quand le sql particulier a été exécuté
SELECT dhs.sql_id, dsn.snap_id, dsn.begin_interval_time, dsn.end_interval_time, ROUND(SUM(dhs.elapsed_time_delta/1000000),0) elapsed_time_secs FROM dba_hist_sqlstat dhs ,v$database d ,dba_hist_snapshot dsn WHERE dhs.dbid = d.dbid AND dsn.snap_id = dhs.snap_id AND dsn.dbid = dhs.dbid AND dsn.instance_number = dhs.instance_number AND dhs.sql_id = '<SQL ID>' AND dsn.snap_id > &begin_snap and dsn.snap_id <= &end_snap GROUP BY dhs.sql_id, dsn.snap_id, dsn.begin_interval_time, dsn.end_interval_time ORDER BY dsn.snap_id;
Où &begin_snap et &end_snap sont les ID d'instantané de début et de fin.
La sortie de cette instruction ressemblera à ce qui suit :
SQL_ID SNAP_ID BEGIN_INTERVAL_TIME END_INTERVAL_TIME ELAPSED_TIME_SECS 2k3uw8n473r30 8278 04-JAN-13 23.00.25.5560 05-JAN-13 00.00.21.1620 23123 2k3uw8n473r30 8279 05-JAN-13 00.00.21.1620 05-JAN-13 01.00.38.2680 37145
Comment trouver les statistiques CBO sur Ebiz Environment
SELECT owner, table_name, num_rows, TO_CHAR(last_analyzed,'DD-MON-YYYY HH24:MI:SS') last_analyzed FROM all_tables WHERE owner IN (SELECT upper(oracle_username) sname FROM fnd_oracle_userid WHERE oracle_id BETWEEN 900 AND 999 AND read_only_flag = 'U' UNION ALL SELECT DISTINCT upper(oracle_username) sname FROM fnd_oracle_userid a,fnd_product_installations b WHERE a.oracle_id = b.oracle_id ) ORDER BY owner, table_name;
La sortie de cette instruction ressemblera à ce qui suit :
OWNER TABLE_NAME NUM_ROWS LAST_ANALYZED --- --------- ---------- ------------------------ ABM ABM_ACC_MAP_SUM_REP 0 06-DEC-2016 08:46:33 ABM ABM_ACT_ACC_RU_DAT 0 06-DEC-2016 08:46:35 ABM ABM_ACT_STA_RU_DAT 0 06-DEC-2016 08:46:36
Comment obtenir les rapports AWR après la mise à niveau
Les rapports AWR peuvent être obtenus pour
• Toute la période d'exécution de la mise à niveau.
• Pour la durée des tâches de longue durée (c'est-à-dire entre les instantanés pris juste avant le démarrage de la tâche et juste après sa fin) .
• Chaque instantané individuel.
Comment générer les rapports AWR
(1) Accédez à $ORACLE_HOME/rdbms/admin
(2) Exécutez awrrpt.sql pour générer les rapports AWR.
(3) Choisissez toujours le type de rapport HTML.
(4) Sur une instance Oracle RAC, awrrpti.sql suffit généralement, car la mise à niveau sera exécutée sur un seul nœud Oracle RAC.
Les rapports AWR peuvent être automatisés. Ceci est utile si vous produisez un grand nombre de rapports AWR, en particulier pour les instantanés successifs. Reportez-vous à la section "Automating AWR Reports" dans le document My Oracle Support "Performance Diagnosis with Automatic Workload Repository (Document 1674086.1)".
Notez que certains objets fixes et objets de dictionnaire (en particulier WRH$_LATCH_CHILDREN, en particulier si statistics_level =ALL, ou il y a une période de rétention élevée ou un court intervalle d'instantané) aura considérablement augmenté pendant la mise à niveau. Il peut donc être nécessaire de collecter des statistiques sur les objets fixes et les dictionnaires avant d'exécuter les AWR.
Articles connexes
Référentiel de charge de travail automatique
Oracle ASH (Active Session History)
Oracle Performance Tuning
Comment créer une tâche ADDM et vérifier son rapport
Comment trouver les détails de la session dans la base de données Oracle