Professional Documents
Culture Documents
Categora Optimizacin
Nivel Medio
Autor JM
Si no existen datos estadsticos para un objeto (por ejemplo, porque se acaba de crear), se
utilizarn valores por defecto. Adems, si los datos estadsticos est anticuados, se corre
el riesgo de calcular costes basados en estadsticas incorrectas, pudiendo ejecutarse
planes
de
ejecucin
que
a
priori
pueden
parecer
mejores.
Por esto, si se utiliza el optimizador basado en costes, es muy importante analizar los
objetos periodicamente (como parte del mantenimiento de la base de datos). Como las
estadsticas van evolucionando en el tiempo (ya que los objetos crecen o decrecen), el
plan de ejecucin se va modificando para optimizarlo mejor a la situacin actual de la
base de datos. El optimizador basado en reglas haca lo contrario: ejecutar siempre el
mismo plan, independientemente del tamao de los objetos involucrados en la consulta.
Dentro de la optimizacin por costes, existen dos modos de optimizacin, configurables
desde el parmetro OPTIMIZER_MODE:
- FIRST_ROWS: utiliza slo un nmero determinado de filas para calcular los planes de
ejecucin. Este mtodo es ms rpido pero puede dar resultados imprecisos.
- ALL_ROWS: utiliza todas las filas de la tabla a la hora de calcular los posibles planes
de ejecucin. Este mtodo es ms lento, pero asegura un plan de ejecucin muy preciso.
Si no se indica lo contrario, este es el mtodo por defecto.
El optimizador basado en costes se utilizar en alguna de las siguientes situaciones:
1.- Si el parmetro OPTIMIZER_MODE del archivo INIT.ORA est definido como
ALL_ROWS
o
FIRST_ROWS.
2.- Si existen estadsticas para alguna de las tablas involucradas en la consulta y el
parmetro
OPTIMIZER_MODE
es
distinto
a
RULE.
3.Si
se
incluye
un
"hint"
distinto
a
+RULE.
4.- Si se ha establecido la variable OPTIMIZER_GOAL a ALL_ROWS o FIRST_ROWS
a
nivel
de
sesin.
5.- En Oracle 7.3, si alguna tabla tiene un grado de paralelismo distinto de 0.
Hay que generar un plan de ejecucin de la consulta a travs del comando EXPLAIN
PLAN. Una vez generado, se debe comprobar la columna POSITION de PLAN_TABLE
para aquellas filas que ID=0. Si el valor de POSITION es NULL, se est usando el
optimizador basado en reglas, en el resto de los casos se utiliza el basado en costes.
El siguiente SELECT nos puede servir para ver el tipo de optimizador utilizado en los
distintos planes:
SELECT
WHERE
DECODE(
NVL(position,-1),-1,
FROM
'Reglas','Costes')
plan_table
id = 0;
sesin.
PLAN.
STATEMENT
ID
INTO
EXPLAIN
PLAN
=
'identificador']
esquema.PLAN_TABLE
plan de ejecucin, podremos mostrar las distintas filas formateadas con la siguiente
consulta:
SELECT
LPAD(
(level-1))
||
operation
FROM
WITH
id
=
statement_id
=
CONNECT
BY
PRIOR
id
=
statement_id = 'identificador';
START
operation,
options,
object_name,
output
0
AND
'identificador'
parent_id
AND
Cmo puedo obtener una traza de todas las sentencias ejecutadas durante una
sesin?
Categora Optimizacin
Nivel Alto
Autor JM
Oracle nos permite obtener una traza de todas las instrucciones que se lancen en una
sesin determinada. Puede ser til para ver el plan de ejecucin de cada una de ellas, para
averiguar las instrucciones SQL que son lanzadas contra una base de datos (cuando no
disponemos de los fuentes de un programa concreto), o incluso para detectar qu
instruccin ralentiza un proceso complejo.
Los pasos a dar son:
a) Obtener el 'sid' y 'serial#' del proceso sobre el que queremos hacer la traza. Para ello
debemos hacer la siguiente consulta sobre V$SESSION:
SELECT
ORDER BY 1, 2;
username,
FROM
program,
sid,
serial#
v$session
USERNAME
--------------SCOTT
PROGRAM
-------------------DELPHI32.EXE
---------
SID
9
SERIAL#
--------30
SYS.DBMS_SYSTEM.set_sql_trace_in_session(9,
30,
TRUE);
END;
Esto nos activa la traza para una sesin identificada por sid y serial#
c) Ejecutar todas las instrucciones sobre las que queremos hacer la traza. Esto puede ser
una instruccin concreta, un proceso completo, o incluso una jornada entera de trabajo
con un programa.
d) Ejecutar de nuevo el bloque de cdigo para desactivar la traza:
BEGIN
END;
SYS.DBMS_SYSTEM.set_sql_trace_in_session(9,
30,
FALSE);
Cuando se hace una consulta y la condicin de filtro incluya una funcin de conversin
(TO_NUMBER, TO_DATE, etc.), esta se debe aplicar siempre que se pueda sobre un
valor
constante
en
vez
de
sobre
una
columna.
Por ejemplo, la siguiente consulta no utilizar ningn indice sobre
<COLUMNA_VARCHAR>
WHERE
FROM
TO_NUMBER(<COLUMNA_VARCHAR>) = 2;
consulta
que
SELECT
utiliza
<COLUMNAS>
<TABLA>
los
SELECT
WHERE
FROM
<COLUMNA_VARCHAR> = TO_CHAR(2);
ndices
sobre
la
<COLUMNAS>
<TABLA>
Las conversiones implcitas siguen unas normas parecidas, pero teniendo en cuenta que
Oracle aplicar la funcin de conversin sobre el valor alfanumrico:
Por ejemplo, esta consulta:
FROM
WHERE
SELECT
<COLUMNAS>
<TABLA>
SELECT
<COLUMNAS>
<TABLA>
<COLUMNA_VARCHAR> = 2;
FROM
TO_NUMBER(<COLUMNA_VARCHAR>) = 2;
Por lo tanto, desactivar los ndices. Sin embargo, esta otra consulta:
SELECT
<COLUMNAS>
<TABLA>
SELECT
FROM
<COLUMNA_VARCHAR> = TO_NUMBER('2');
<COLUMNAS>
<TABLA>
FROM
WHERE
<COLUMNA_NUMBER> = '2';
Por lo que no desactivar los ndices, ya que la funcin se aplica sobre el valor constante
y no sobre la columna.