Home > Oracle > Oracle RAC (tuning de sql)

Oracle RAC (tuning de sql)

Existen muchas empresas que empiezan a pensar que Oracle RAC sería una buena solución de alta disponibilidad para sus aplicaciones. Probablemente lo sea, pero requiere de un estudio en profundidad que desgraciadamente no se hace a menos que se recurra a mano de obra experta. Este es el caso de una reciente instalación de Oracle RAC que el cliente en cuestión, se dedicó a hacer el import y a poner el sistema en producción ….., claro, para qué va a pasar estadísticas si existe el maravilloso dynamic sampling !A partir de versión 10g, el valor de optimizer_dynamic_sampling viene por defecto a 2. En oracle RAC, no tener estadísticas en las tablas y dejando el valor por defecto del parámetro de muestreo, provoca envíos adicionales de CR blocks y en un sistema transaccional puede representar una degradación de rendimiento apreciable en momentos puntuales.

En mi caso, me limité a analizar las tablas y solucioné el problema, aunque configurando el parámetro optimizer_dynamic_sampling a 1 también minimiza el impacto del dynamic sampling.

Testcase

SQL> select * from tab;

TNAME TABTYPE CLUSTERID
—————————— ——- ———-
OBJETOS TABLE

SQL> show parameter optimizer_dy

NAME TYPE VALUE
———————————— ———– ——————————
optimizer_dynamic_sampling integer 2

SQL> select last_analyzed, num_rows from dba_tables where table_name =’OBJETOS’;

LAST_ANA NUM_ROWS
——– ———-
10/07/06 49903

SQL> exec dbms_stats.delete_table_stats(‘demo’, ‘objetos’)
PL/SQL procedure successfully completed.

SQL> select last_analyzed, num_rows from dba_tables where table_name =’OBJETOS’;

LAST_ANA NUM_ROWS
——– ———-

SQL> alter session set events ’10046 trace name context forever, level 8′;
Session altered.

SQL> select count(*) from objetos where object_type = ‘SYNONYM’;

COUNT(*)
———-
20028

SQL> alter session set events ’10046 trace name context off’;
Session altered.

– Salida tkprof

SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE
NO_PARALLEL(SAMPLESUB) opt_param(‘parallel_execution_enabled’, ‘false’)
NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE */ NVL(SUM(C1),:”SYS_B_0″),
NVL(SUM(C2),:”SYS_B_1″)
FROM
(SELECT /*+ IGNORE_WHERE_CLAUSE NO_PARALLEL(“OBJETOS”) FULL(“OBJETOS”)
NO_PARALLEL_INDEX(“OBJETOS”) */ :”SYS_B_2″ AS C1, CASE WHEN
“OBJETOS”.”OBJECT_TYPE”=:”SYS_B_3″ THEN :”SYS_B_4″ ELSE :”SYS_B_5″ END AS
C2 FROM “OBJETOS” SAMPLE BLOCK (:”SYS_B_6″ , :”SYS_B_7″) SEED (:”SYS_B_8″)
“OBJETOS”) SAMPLESUB

call count cpu elapsed disk query current rows
——- —— ——– ———- ———- ———- ———- ———-
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.01 0 0 0 0
Fetch 1 0.00 0.31 321 71 0 1
——- —— ——– ———- ———- ———- ———- ———-
total 3 0.00 0.33 321 71 0 1

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 54 (recursive depth: 1)

Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
—————————————- Waited ———- ————
db file scattered read 21 0.02 0.18
db file sequential read 9 0.00 0.01
gc cr grant 2-way 3 0.00 0.00
gc cr multi block request 9 0.00 0.02
********************************************************************************

SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS opt_param(‘parallel_execution_enabled’,
‘false’) NO_PARALLEL(SAMPLESUB) NO_PARALLEL_INDEX(SAMPLESUB) NO_SQL_TUNE
*/ NVL(SUM(C1),:”SYS_B_0″), NVL(SUM(C2),:”SYS_B_1″), NVL(SUM(C3),:”SYS_B_2″)

FROM
(SELECT /*+ NO_PARALLEL(“OBJETOS”) INDEX(“OBJETOS” TIPO_OBJETO)
NO_PARALLEL_INDEX(“OBJETOS”) */ :”SYS_B_3″ AS C1, :”SYS_B_4″ AS C2,
:”SYS_B_5″ AS C3 FROM “OBJETOS” “OBJETOS” WHERE “OBJETOS”.”OBJECT_TYPE”=
:”SYS_B_6″ AND ROWNUM <= :”SYS_B_7″) SAMPLESUB

call count cpu elapsed disk query current rows
——- —— ——– ———- ———- ———- ———- ———-
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.06 9 9 0 1
——- —— ——– ———- ———- ———- ———- ———-
total 3 0.00 0.07 9 9 0 1

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 54 (recursive depth: 1)

Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
—————————————- Waited ———- ————
gc cr grant 2-way 9 0.00 0.01
db file sequential read 9 0.01 0.02
********************************************************************************

Total eventos

Event waited on Times Max. Wait Total Waited
—————————————- Waited ———- ————
library cache lock 6 0.01 0.01
gc cr grant 2-way 12 0.00 0.01
db file sequential read 18 0.01 0.04
db file scattered read 21 0.02 0.18
gc cr multi block request 9 0.00 0.02

En el caso de que el índice de volatilidad de la tabla sobre la que realizamos repetidas consultas sea alto, se generarán esperas notables provocadas por el muestreo automático que tal como se demuestra, genera envíos extra de bloques CR. La recomendación que suelo hacer es que se pasen estadísticas. Esta nota está basada en una experiencia y no significa que dynamic sampling no deba utilizarse.

Categories: Oracle Tags:
  1. No comments yet.
  1. No trackbacks yet.