2026-03-12 21:01:38
This commit is contained in:
141
tiddlywiki/SQL Profile from AWR.txt
Executable file
141
tiddlywiki/SQL Profile from AWR.txt
Executable file
@@ -0,0 +1,141 @@
|
||||
-- SQL Profile -- chargement à partir d'un plan d'exécution du Library Cache
|
||||
-- d'après le blog de Kerry Osborne ( http://kerryosborne.oracle-guy.com/2009/04/oracle-sql-profiles/ )
|
||||
-- et un exemple de Christian Antognini ( http://antognini.ch/top/ )
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (id, col1, col2, pad)
|
||||
AS
|
||||
SELECT rownum, CASE WHEN rownum>5000 THEN 5000 ELSE rownum END, rownum, lpad('*',100,'*')
|
||||
FROM dual
|
||||
CONNECT BY level <= 10000;
|
||||
|
||||
CREATE INDEX t1_col1 ON t1 (col1);
|
||||
|
||||
-- Calcul des statistiques avec des histogrammes automatiques
|
||||
BEGIN
|
||||
dbms_stats.gather_table_stats(
|
||||
ownname=>user,
|
||||
tabname=>'T1',
|
||||
cascade=>TRUE,
|
||||
estimate_percent=>100,
|
||||
method_opt=>'for all columns size skewonly',
|
||||
no_invalidate=>FALSE);
|
||||
END;
|
||||
/
|
||||
|
||||
-- Du moment que cursor_sharing n'est pas FORCE, des plans d'exécution differents sont
|
||||
-- générés en foction de la valeur du litteral
|
||||
-- On peut vérifier avec une 2ème session SYSDBA et les requêtes suivantes:
|
||||
-- SQL> select sid,serial#,SQL_ID,SQL_CHILD_NUMBER,PREV_SQL_ID,PREV_CHILD_NUMBER from v$session where username=&username;
|
||||
-- SQL> select * from table(dbms_xplan.display_cursor(&SQL_ID,&SQL_CHILD_NUMBER,'typical'));
|
||||
-- probablement &PREV_SQL_ID et &PREV_CHILD_NUMBER car les requêtes sont rapides
|
||||
|
||||
|
||||
-------------------------------------
|
||||
-- Dans une 2ème session AS SYSDBA =>
|
||||
-- nettoyage du Library Cache
|
||||
alter system flush shared_pool;
|
||||
-------------------------------------
|
||||
-- Session applicative =>
|
||||
-- FULL SCAN
|
||||
select * from t1 where col1=5000;
|
||||
|
||||
-- Dans une 2ème session AS SYSDBA =>
|
||||
-- 1er snapshoot AWR
|
||||
execute dbms_workload_repository.CREATE_SNAPSHOT;
|
||||
|
||||
|
||||
-- Session applicative =>
|
||||
-- ACCES PAR INDEX
|
||||
select * from t1 where col1=128;
|
||||
|
||||
|
||||
-- Dans une 2ème session AS SYSDBA =>
|
||||
-- 2ème snapshoot AWR
|
||||
execute dbms_workload_repository.CREATE_SNAPSHOT;
|
||||
|
||||
------------------------------------------------------
|
||||
-- SESSION 2 as SYSDBA
|
||||
-- on récupère le SQL_ID, ainsi que le Plan hash value du SQL qui fait en FULL
|
||||
|
||||
set pages 999
|
||||
set line 200
|
||||
col SQL_TEXT for a70 wrap
|
||||
|
||||
select dbid,sql_id,sql_text from DBA_HIST_SQLTEXT where SQL_TEXT like '%select * from t1 where col1=%';
|
||||
|
||||
select * from table(dbms_xplan.display_awr('b9tum9b80gsjx')); -- FULL
|
||||
|
||||
-- Nous alons créer un SQL Profile qui utilise ce denier plan d'exécution (FULL)
|
||||
-- les valeurs d'entrée:
|
||||
-- sql_id = 'b9tum9b80gsjx' / plan_hash_value=3617692013 / category => 'SQLPROF_CAT_01' / name => 'SQLPROF_SQLPROF_02' / force_match => true
|
||||
|
||||
/* Randolf Giest */
|
||||
-- create sql profile from awr
|
||||
-- sql_id plan_hash_valeu category force_matching
|
||||
declare
|
||||
ar_profile_hints sys.sqlprof_attr;
|
||||
cl_sql_text clob;
|
||||
begin
|
||||
select
|
||||
extractvalue(value(d), '/hint') as outline_hints
|
||||
bulk collect
|
||||
into
|
||||
ar_profile_hints
|
||||
from
|
||||
xmltable('/*/outline_data/hint'
|
||||
passing (
|
||||
select
|
||||
xmltype(other_xml) as xmlval
|
||||
from
|
||||
dba_hist_sql_plan
|
||||
where
|
||||
sql_id = 'b9tum9b80gsjx'
|
||||
and plan_hash_value = 3617692013
|
||||
and other_xml is not null
|
||||
)
|
||||
) d;
|
||||
|
||||
select
|
||||
sql_text
|
||||
into
|
||||
cl_sql_text
|
||||
from
|
||||
dba_hist_sqltext
|
||||
where
|
||||
sql_id = 'b9tum9b80gsjx';
|
||||
|
||||
dbms_sqltune.import_sql_profile(
|
||||
sql_text => cl_sql_text
|
||||
, profile => ar_profile_hints
|
||||
, category => 'SQLPROF_CAT_01'
|
||||
, name => 'SQLPROF_SQLPROF_02'
|
||||
-- use force_match => true
|
||||
-- to use CURSOR_SHARING=SIMILAR
|
||||
-- behaviour, i.e. match even with
|
||||
-- differing literals
|
||||
, force_match => true
|
||||
);
|
||||
end;
|
||||
/
|
||||
|
||||
-- On vérifie que le SQL Plan a été créé
|
||||
-- normallement c'est afficher dans la note
|
||||
|
||||
set line 128
|
||||
col sql_text for a40 wrap
|
||||
select name,category,sql_text,status,force_matching from DBA_SQL_PROFILES;
|
||||
|
||||
------------------------------------------------------
|
||||
-- On reviens dans la première session (celle applicative)
|
||||
-- on change la catègorie courante de SQL Tune
|
||||
-- on vérifie que le pla d'exécution est bien celui du SQL Profile
|
||||
|
||||
alter session set sqltune_category='SQLPROF_CAT_01';
|
||||
|
||||
explain plan for select * from t1 where col1=5000;
|
||||
select * from table(dbms_xplan.display);
|
||||
|
||||
explain plan for select * from t1 where col1=1200;
|
||||
select * from table(dbms_xplan.display);
|
||||
Reference in New Issue
Block a user