0] Miscellanous
0.1 Checklist to get same
execution plan between 2 databases
Same objects structure ( index … )
Objects Statistics
Optimizer parameters including PGA settings
Systems statistics
0.2 How to get rid of -
'PLAN_TABLE' is old version
SQL> drop table plan_table ;
Table dropped.
SQL> @$ORACLE_HOME/rdbms/admin/utlxplan.sql
Table created.
0.3 Modify Session Optimizer
parameters
Using the Logon Trigger seen
for Audit, we can add
--
B/ Outlines
execute immediate 'alter session set use_stored_outlines=TRUE';
--
C/ Set parameter
if ( user in ('SCH_ADMIN', 'SCH_BO','SCH_reference','SCH_PROC','SCH_CONFIG50005') ) then
execute immediate 'alter session set recyclebin = OFF';
end if;
--
D/ SQL Trace
--- if ( user in ('USR') ) then
--- execute immediate 'alter session set
sql_trace=true';
--- end if;
--
E/ Compatible 9i
if ( user in ('USR1','USR2') ) then
EXECUTE IMMEDIATE 'alter session set "_OPTIMIZER_COST_BASED_TRANSFORMATION" = off';
EXECUTE IMMEDIATE
'alter session set optimizer_features_enable=''10.2.0.3''';
end if;
0.4 See which level of
optimizer a session is in
select sid,NAME,VALUE from v$ses_optimizer_env
where ( name like '%optim%feat%' or name like '%optim%mode%' ) and sid in (select sid from v$session where username = 'SCH' and sid = 499 or sid = 494 )
SID NAME VALUE
494 optimizer_features_enable 10.2.0.3
494 optimizer_mode first_rows
499 optimizer_features_enable 10.2.0.5
499 optimizer_mode all_rows
0.5 How to Trace a session
- Using the Logon trigger, assuming that SYSTEM
gets the right to do it ( grant alter session to system ; ) :
-- E/ SQL Trace
if (
user in ('USR') ) then
execute immediate 'alter session set sql_trace=true';
end if;
CREATE OR REPLACE TRIGGER DB_LOGON_TRC
after logon on database
begin
if (
user in ('USR') ) then
execute
immediate 'ALTER SESSION SET EVENTS ''10046 trace name context forever, level
12'' ';
end if;
end;
/
- Trace an existing Session :
sys.dbms_system.set_ev(user_sid,
user_serial#, 10046, N, '');
EXECUTE
SYS.DBMS_SYSTEM.SET_EV (118, 2940, 10046, 12, ''); -- -> enable tracing
EXECUTE
SYS.DBMS_SYSTEM.SET_EV (118, 2940, 10046, 0, ''); -- -> disable tracing
select 'EXECUTE SYS.DBMS_SYSTEM.SET_EV('||SID||','||SERIAL#||',10046,12,'''') ;' from v$session where SID=11
For methods that require
tracing levels the following are valid values.
0 - No trace. Like switching
sql_trace off.
2 - The equivalent of regular
sql_trace.
4 - The same as 2, but with
the addition of bind variable values.
8 - The same as 2, but with
the addition of wait events.
12 - The same as 2, but with
both bind variable values and wait events.
TRACE w/ Bind Variables :
PARSING IN CURSOR
#2 len=210 dep=0 uid=855 oct=2 lid=855 tim=3809739329401 hv=1326906613
ad='3460f990'
insert into
APP.MESSAGES (BODY, CALL_DATE, CALLER, CREATION_DATE, IS_URGENT,
MODIFICATION_DATE, SOURCE_AGENT_ID, SOURCE_LOGIN, SUBJECT, TARGET_AGENT_ID, ID)
values (:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11)
END OF STMT
PARSE
#2:c=0,e=61,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=3809739329399
BINDS #2:
kkscoacd
Bind#0
oacdty=01 mxl=32(15) mxlc=00 mal=00 scl=00
pre=00
oacflg=03 fl2=1000010 frm=01 csi=178 siz=248
off=0
kxsbbbfp=110ae2120 bln=32
avl=15 flg=05
value="body_2147483647"
-- find easily the trc files from spid information
select sysdate TS, s.username , s.logon_time , s.server , p.spid from
v$session s , v$process p
where s.username = '<USER>' and s.paddr=p.addr order by
logon_time desc
Caution : the SPID in case of
Shared Server gives the Dispatcher’s PID.
0.6 plan_hash_value is changing
with character set
Same code, different character
set ( Oracle 10 and 11 )
set pages 5000 lines 150
set timing on ;
set autotrace traceonly ;
select /*+ INDEX_FFS (a, PK_TABLE1)
*/ count(1) from ADB.TABLE1 a ;
exit
UTF-8 11G Plan hash value: 136383568
------------------------------------------------------------------------------
|
Id | Operation | Name | Rows
| Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |
747 (2)| 00:00:09 |
| 1 |
SORT AGGREGATE | | 1 | | |
| 2 |
INDEX FAST FULL SCAN| PK_TABLE1 |
690K| 747 (2)| 00:00:09 |
------------------------------------------------------------------------------
WE8MSWIN1252 11G Plan hash value: 1689933652
------------------------------------------------------------------------------
|
Id | Operation | Name | Rows
| Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |
759 (3)| 00:00:10 |
| 1 |
SORT AGGREGATE | | 1 | | |
| 2 |
INDEX FAST FULL SCAN| PK_TABLE1 |
690K| 759 (3)| 00:00:10 |
------------------------------------------------------------------------------
WE8MSWIN1252 10G Plan hash value: 1689933652
------------------------------------------------------------------------------
|
Id | Operation | Name | Rows
| Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |
412 (2)| 00:00:05 |
| 1 |
SORT AGGREGATE | | 1 | | |
| 2 |
INDEX FAST FULL SCAN| PK_TABLE1 |
690K| 412 (2)| 00:00:05 |
------------------------------------------------------------------------------
1] V$SQL : in-memory SQL
1.0 Get Top SQL from V$SQL
select sql_id ,
plan_hash_value ,
parsing_schema_name ,
executions , buffer_gets , disk_reads ,
first_load_time , rows_processed , elapsed_time ,
last_load_time , sql_text from v$sql
where buffer_gets > 10000
order by
buffer_gets/executions desc
select sql_id ,
plan_hash_value ,
parsing_schema_name ,
executions , buffer_gets , disk_reads ,
first_load_time , rows_processed , elapsed_time ,
last_load_time , sql_text from v$sql
where upper(sql_text) like '%SELECT%TRUNC(TABLE1.HEURE)%'
order by buffer_gets/executions
desc
select sql_id ,
plan_hash_value ,
parsing_schema_name ,
executions , buffer_gets , disk_reads ,
first_load_time , rows_processed , elapsed_time/1000000 Sec , last_load_time , sql_text from v$sql
where sql_id = '5865vav66abys'
1.1 Get SQL text from SID
-- how to
get sql from session SID in sqlarea memory
select a.sid, a.serial#, b.sql_text from v$session a, v$sqlarea b where a.sql_address=b.address and a.sid = 1260;
select a.sid, a.serial#, b.sql_id , b.sql_text from v$session a, v$sqlarea
b where a.sql_address=b.address and a.username = '50004'
select a.sid, a.serial# ,
b.sql_id , b.plan_hash_value , b.sql_text from v$session a, v$sqlarea b where
a.sql_address=b.address and a.sid = 988 -- cjadkfgvtkm52 / 2199050946
1.2 Get Explain Plan, using
DBMS_XPLAN.display_cursor
select sid , a.sql_id , child_number from v$session a , v$sql b where a.sql_id=b.sql_id and a.sid = '1744' ;
SELECT * FROM TABLE (DBMS_XPLAN.display_cursor ('&sql_id', '&child_number', 'ADVANCED'));
1.3 Get Bind Variables, using $SQL_BIND_CAPTURE
& SQL_ID
SELECT sql_id, child_number, name,
position, datatype_string,
value_string, last_captured
FROM V$SQL_BIND_CAPTURE
WHERE sql_id = 'fhnjysdwnr9rf'
ORDER BY sql_id, child_number, name ;
2] Query Tuning : when
having the code
2.0 Run SQL with assigned bind
variables, using SQLPLUS
set pages 5000
lines 150
set timing on
;
var
Date_ref_Debut varchar2(15) ;
var
Date_ref_Fin varchar2(15) ;
exec
:Date_ref_Debut:='31/05/2012' ;
exec :Date_ref_Fin:='31/05/2012'
;
2.1 Get Real Execution Plan
& Statistics
- Add the
following lines at the beginning of SQL script, to execute the query,
without printing returned rows
set pages 5000
lines 150
set timing on
;
set autotrace
traceonly ;
- Run it
– complete Log
$ sqlplus <con_string> @<sonde>.sql | tee
<sonde>.log
SQL*Plus: Release 10.2.0.5.0 - Production on Thu Jun 9
14:18:42 2011
Copyright (c) 1982, 2010, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release
10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real
Application Testing options
10000 rows selected.
Elapsed: 00:00:08.39
Execution Plan
----------------------------------------------------------
Plan hash value: 1751135198
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 927 | 58401 | 354
(5)| 00:00:05 |
| 1 |
WINDOW BUFFER
| | 927 | 58401 | 354
(5)| 00:00:05 |
|* 2 |
COUNT STOPKEY
| | |
| | |
|* 3 |
FILTER
| | |
| | |
| 4 |
TABLE ACCESS BY INDEX ROWID |
GROUPES_SYSTEMES_V2 | 13460 | 828K|
354 (5)| 00:00:05 |
| 5 |
INDEX FULL SCAN |
GROUPES_SYSTEMES_V2_PK | 13460 | |
77 (2)| 00:00:01 |
| 6 |
NESTED LOOPS
|
| 1 | 83 |
6 (0)| 00:00:01 |
| 7 |
NESTED LOOPS | | 1 |
60 | 4 (0)| 00:00:01 |
|* 8 |
INDEX RANGE SCAN | GROUPES_COMPTES_V2_I3 |
1 | 46 | 3
(0)| 00:00:01 |
| 9 |
TABLE ACCESS BY INDEX ROWID| UTILISATEUR | 1 |
14 | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | UTILISATEUR_UK_I2U |
1 | | 0
(0)| 00:00:01 |
| 11 |
INLIST ITERATOR | | |
| | |
|* 12 | INDEX UNIQUE SCAN | UK_FONCTIONS_METIERS_PAR_UO | 1 |
23 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 -
filter(ROWNUM<=10000)
3 -
filter("<SCHEMA>I2U_FIND_PROFIL"('CCERVANTES')='ADMIN_SYST'
OR EXISTS (SELECT 0 FROM
"FONCTIONS_METIERS_PAR_UO"
"FONCTIONS_METIERS_PAR_UO","UTILISATEUR"
"UTILISATEUR","GROUPES_COMPTES_V2"
"G2" WHERE "G2"."GROUPE"=:B1 AND
"G2"."CONTAINER"=:B2 AND
"G2"."ARBRE"=:B3 AND "G2"."SYSTEME"=:B4
AND
"UTILISATEUR"."LOGIN_NAME_UNIQUE"="G2"."I2U"
AND "FONCTIONS_METIERS_PAR_UO"."LOGIN_NAME_UNIQUE"='CCERVAN
TES' AND ("FONCTIONS_METIERS_PAR_UO"."COD_FONCTION"='CORR_INFO'
OR
"FONCTIONS_METIERS_PAR_UO"."COD_FONCTION"='CORR_INFO_ADJ')
AND
"UTILISATEUR"."UO_ID"="FONCTIONS_METIERS_PAR_UO"."UO_ID")
OR
"<SCHEMA>I2U_FIND_PROFIL"('CCERVANTES')='ADMIN_I2U')
8 - access("G2"."SYSTEME"=:B1
AND "G2"."ARBRE"=:B2 AND
"G2"."CONTAINER"=:B3 AND
"G2"."GROUPE"=:B4)
10 -
access("UTILISATEUR"."LOGIN_NAME_UNIQUE"="G2"."I2U")
12 -
access("UTILISATEUR"."UO_ID"="FONCTIONS_METIERS_PAR_UO"."UO_ID"
AND
("FONCTIONS_METIERS_PAR_UO"."COD_FONCTION"='CORR_INFO'
OR
"FONCTIONS_METIERS_PAR_UO"."COD_FONCTION"='CORR_INFO_ADJ')
AND
"FONCTIONS_METIERS_PAR_UO"."LOGIN_NAME_UNIQUE"='CCERVANTES')
Statistics
----------------------------------------------------------
20001 recursive calls
0 db block gets
1893729 consistent gets
0 physical reads
0 redo size
606561 bytes sent via SQL*Net to client
7889 bytes received via SQL*Net from client
668 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
10000 rows processed
Disconnected from Oracle Database 10g Enterprise
Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real
Application Testing options
- Run it
and filter results to get SQL Response Time
Create a bench Query to get
daily performance Database Performance All
subsystems ( Server , Storage )
Get Real
DB Blocks Read as follow :
$ time sqlplus system@<db_name>d
@hr_bo_sonde_1.sql | egrep -i "consistent gets|physical reads"
1128153 consistent gets
210337 physical reads
real
1m12.232s
Note : not possible to
get block stats on a Standby DB Open in READ-ONLY mode.
$ time sqlplus hr_bo@hr_bo_sonde_1_RO.sql >
/dev/null
real
30m16.299s
2.2 Get detailed Explain Plan, without running the Query
explain plan for
SELECT mes.id_egst
FROM gen.mes, gen.asm, gen.cod_mes
WHERE mes.cd_codmes_mes = cod_mes.cd_cod_mes
AND RTRIM (cod_mes.cd_catmes_cod_mes) = :kslvar16_
AND mes.in_refagr_mes = 'R'
AND (spe5.pkg_gen__sel_data_asm.f_get_dt_fin_agr (mes.id_perben_mes,
DECODE (:kslvar16_,
'AGRANP', 'N',
'P'
)
)
) > TO_DATE (:kslvar15_, 'DD/MM/YYYY')
AND (spe5.pkg_gen__sel_data_asm.f_get_dt_fin_agr (mes.id_perben_mes,
DECODE (:kslvar16_,
'AGRANP', 'N',
'P'
)
) <
TO_DATE (:kslvar14_, 'DD/MM/YYYY')
)
AND mes.id_perben_mes = asm.id_egst
AND ( mes.id_egst = asm.id_der_mes_p_dec_asm
OR mes.id_egst = asm.id_der_mes_np_dec_asm
)
ORDER BY 1
select * from table(dbms_xplan.display('PLAN_TABLE',null,'ADVANCED')) ;
PLAN_TABLE_OUTPUT
49 -
filter("AAS"."AAS_DAT_FIN" IS NULL AND
"AAS"."AAS_ACT_NUM_INT">=0 AND
"AAS"."AAS_ACT_NUM_INT"<=9999999)
50 -
filter("DOS"."DOS_DAT_CLO" IS NULL AND
"DOS"."DOS_DAT_ARCHIVE" IS NULL)
3] Index
3.1 Big Tables without any
Index
select owner , table_name ,
num_rows from dba_tables a where a.owner = 'BI_APP_DTM'
and num_rows > 1000000
and not exists ( select '1'
from dba_indexes b where a.table_name = b.table_name )
order by 3 desc
4] The effect of Version or
Character Set on Full Scan
4.1 Full scan are more efficient
in 11G than 10G
Same code, same machine, but
11G does Direct Read ( bypasses buffer cache )
set pages
5000 lines 150
set timing
on ;
set
autotrace traceonly ;
select /*+
FULL (a) */ count(1) from ADB.TABLE1 a ;
exit
WE8MSWIN1252 10G Elapsed: 00:00:06.57
Plan
hash value: 2121393994
------------------------------------------------------------------------
|
Id | Operation | Name | Rows
| Cost (%CPU)| Time |
------------------------------------------------------------------------
| 0 |
SELECT STATEMENT | |
1 | 16943 (1)| 00:03:24 |
| 1 |
SORT AGGREGATE | |
1 | | |
| 2 |
TABLE ACCESS FULL| TABLE1 |
690K| 16943 (1)| 00:03:24 |
------------------------------------------------------------------------
62081
consistent gets
62028
physical reads
WE8MSWIN1252 11G Elapsed: 00:00:04.72
Plan hash
value: 2121393994
62041
consistent gets
62028
physical reads
4.2 Full scan read more blocks
in Unicode
Same code, same machine, but
UTF-8 response time * 1.8 vs WE8MSWIN1252
UTF-8 11G Elapsed: 00:00:11.98
Plan
hash value: 3761518470
------------------------------------------------------------------------
|
Id | Operation | Name | Rows
| Cost (%CPU)| Time |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT |
| 1 | 27681 (1)| 00:05:33 |
| 1 |
SORT AGGREGATE | |
1 | | |
| 2 |
TABLE ACCESS FULL| TABLE1 |
690K| 27681 (1)| 00:05:33 |
------------------------------------------------------------------------
101574
consistent gets
101555
physical reads
5] The 11G+ Result Cache
Good when there are few rows
returned, frequent executions and the source tables aren’t modify too often.
I’m using it in a View.
5.1 Setup
$ sqlplus / as sysdba
SQL> sho parameter result
NAME TYPE VALUE
------------------------------------
----------- ------------------------------
client_result_cache_lag big integer 3000
client_result_cache_size big integer 0
result_cache_max_result integer 5
result_cache_max_size big integer 13088K
result_cache_mode string MANUAL
result_cache_remote_expiration integer 0
SQL>
SQL> alter system set
result_cache_max_size = 64M ;
System altered.
Modify the view : it is
unnecessary to add the hint in the sub-query ( won’t be cached ).
CREATE or replace VIEW OWNER.V_MY_VIEW
(NUMEQUIPEMENT, NOM, ID_SOCIETE,
TYPESESSION)
AS
SELECT /*+ result_cache */code_equipement,
NULL AS nom,
id_societe,
typesession
FROM t_tab01
WHERE (
t_tab01.typesession = 10 AND
NOT EXISTS
(SELECT *
FROM T_TAB02
WHERE
id_typeequipement IN (10,20)
AND T_TAB02.numequipement = T_TAB01.code_equipement
AND t_tab02.id_societe =T_TAB01.id_societe
)
)
/
5.2 Check that the Result
Cache is working
explain plan for
select count(1) from OWNER.V_MY_VIEW -- 79330
select * from table(dbms_xplan.display('PLAN_TABLE',null,'ADVANCED')) ;
PLAN_TABLE_OUTPUT
Plan hash value: 830699133
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |
| 18 (6)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 |
| | |
| 2 | VIEW | V_MY_VIEW | 174 | |
18 (6)| 00:00:01 |
| 3 | RESULT CACHE |
fs0pw9ht8j22k9x7n21xdub6bn | |
| | |
|* 4 | HASH JOIN ANTI | | 174 |
4002 | 18 (6)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID | T_TAB01 | 220 |
2420 | 13 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | I_T_TAB01_TYPESESSION |
220 | | 3
(0)| 00:00:01 |
| 7 | INLIST ITERATOR | | |
| | |
| 8 | TABLE ACCESS BY INDEX ROWID| T_TAB02 | 42 |
504 | 4 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | I_ID_TYPEEQUIPEMENT |
42 | | 2
(0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------
5.3 Get the statistics about
the Result Cache
select * from v$result_cache_statistics ;
215 Create Count Success Number of cache results successfully created
0 Create Count Failure Number of cache results that failed to create
5227
Find Count Number of cached results that were successfully found
187 Invalidation Count Total number of invalidations
205 Delete Count Invalid Number of invalid cached results deleted
0 Delete Count Valid Number of valid cached results deleted
select * from v$result_cache_objects order by
creation_timestamp ;
select type , status , substr(name,1,15) ,
namespace ,
creation_timestamp from
v$result_cache_objects order by creation_timestamp ;
TYPE
|
STATUS
|
SUBSTR(NAME,1,15)
|
NAMESPACE
|
CREATION_TIMESTAMP
|
Dependency
|
Published
|
OWNER.T_TAB02
|
|
12/12/2014 15:10
|
Dependency
|
Published
|
OWNER.T_TAB01
|
|
15/12/2014 14:16
|
Result
|
Invalid
|
SELECT /*+ resu
|
SQL
|
18/12/2014 10:48
|
Result
|
Published
|
SELECT /*+ resu
|
SQL
|
18/12/2014 16:25
|
Status
Invalid : dependent
tables were modified, the result gets Invalid, will be deleted from the result
cache ; the results from the next execution will be cached
New : is beeing
executed
Published : result
is good to be used
Others
select * from v$result_cache_memory
select * from
v$result_cache_dependency
Real world : elapsed time
jeu. déc. 18 16:09:23 CET 2014
2127 rows selected.
Elapsed: 00:00:00.19 =>
result cache used
jeu. déc. 18 16:14:23 CET 2014
2127 rows selected.
Elapsed: 00:00:00.23 =>
result cache used
jeu. déc. 18 16:19:24 CET 2014
2127 rows selected.
Elapsed: 00:00:00.20 =>
result cache used
jeu. déc. 18 16:24:25 CET 2014
2127 rows selected.
Elapsed: 00:02:03.14 => result cache not used, tables
were modified
jeu. déc. 18 16:31:29 CET 2014
2127 rows selected.
Elapsed: 00:00:00.17 =>
result cache used
jeu. déc. 18 16:36:30 CET 2014
2127 rows selected.
Elapsed: 00:00:00.16 =>
result cache used