Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Una Búsqueda Secuencial de Tabla Completa lee cada fila de una tabla.
Para optimizar la performance de una búsqueda de tabla completa, ORACLE lee
múltiples bloques durante cada lectura de la base de datos.
Una búsqueda completa a la tabla es utilizada siempre que no exista
cláusula where en una Consulta.
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Seleccionar la Secuencia de Nombre de Tablas más Eficiente
Por Ejemplo:
Mejor Performance:
SELECT COUNT(*) FROM TAB1, TAB2 0.96
segundos
Peor Performance:
SELECT COUNT(*) FROM TAB2, TAB1 26.09
segundos
Por Ejemplo:
SELECT . . .
FROM UBICACION U,
CATEGORÍA C,
EMP E
WHERE E.EMP_NO BETWEEN 1000 AND 2000
AND E.CAT_NO = C.CAT_NO
AND E.UBICA = U.UBICA
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Es más eficiente que:
SELECT . . .
FROM EMP E,
UBICACIÓN U,
CATEGORIA C
WHERE E.CAT_NO = C.CAT_NO
AND E.UBICA = L.UBICA
AND E.EMP_NO BETWEEN 1000 AND 2000
Los JOINS que relacionan Tablas debieran ser escritos primero que
cualquier condición de la cláusula WHERE. Y las condiciones que filtran el máximo de
registros debieran ser ubicadas al final de los JOINS.
Por Ejemplo:
SELECT . . . .
FROM EMP E
WHERE SAL > 50000
AND JOB = ‘DIRECTOR’
AND 25 < (SELECT COUNT(*)
FROM EMP
WHERE MGR = E.EMPNO);
SELECT . . . .
FROM EMP E
WHERE 25 < (SELECT COUNT(*)
FROM EMP
WHERE MGR = E.EMPNO )
AND SAL > 50000
AND JOB = ‘DIRECTOR’;
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Uso del * en instrucciones SELECT
La referencia (*) entrega una manera de referenciar todas las columnas
de la tabla. No use la característica (*) porque es muy ineficiente ya que el * debe ser
convertido en cada columna. El análisis de todos los campos referenciados obteniendo
todos los nombres de columnas desde el diccionario de datos y sustituyéndolos en la
línea de comando, lo cual consume tiempo.
Por Ejemplo:
Método 2 (Eficiente):
DECLARE
CURSOR C1(E_NO NUMBER) IS
SELECT EMP_NAME, SALARY, GRADE
FROM EMP
WHERE EMP_NO = E_NO;
BEGIN
OPEN C1(342);
FETCH C1 INTO …, …, …;
....
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
....
OPEN C1(291);
FETCH C1 INTO …, …, …;
CLOSE C1;
END;
Por Ejemplo:
Usted puede alcanzar el mismo resultado mucho más eficientemente con el DECODE:
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
De manera similar, DECODE puede ser usado con GROUP BY u ORDER BY
efectivamente.
Combinando Accesos a Bases de Datos Simple y sin relación.
Por Ejemplo:
SELECT NAME
FROM EMP
WHERE EMP_NO = 1234;
SELECT NAME
FROM DPT
WHERE DPT_NO = 10;
SELECT NAME
FROM CAT
WHERE CAT_TYPE = 'RD';
Las tres consultas anteriores pueden ser combinadas como se muestra a continuación:
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Borrando Registros Duplicados
Cuando las filas son removidas desde una tabla, bajo circunstancias
normales, los segmentos de ROLLBACK son usados para almacenar información de
respaldo; si no se realiza COMMIT de la transacción, Oracle recupera los datos en el
mismo estado que se encontraban antes que la transacción comenzara.
Con TRUNCATE, ninguna información de respaldo es generada. Una vez
que la tabla ha sido truncada, los datos no pueden ser recuperados. Es más rápido y
necesita menos recursos.
Use TRUNCATE en vez de DELETE para limpiar los contenidos de tablas
pequeñas o grandes cuando no se necesita que se genere información de
recuperación.
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Ejecución Frecuente de Instrucciones COMMIT
Por Ejemplo:
Menos Eficiente:
Más Eficiente:
Por Ejemplo:
Menos Eficiente:
SELECT TAB_NAME
FROM TABLES
WHERE TAB_NAME = (SELECT TAB_NAME
FROM TAB_COLUMNS
WHERE VERSION = 604)
AND DB_VER = (SELECT DB_VER
FROM TAB_COLUMNS
WHERE VERSION = 604)
Más Eficiente:
SELECT TAB_NAME
FROM TABLES
WHERE (TAB_NAME, DB_VER) = (SELECT TAB_NAME, DB_VER
FROM TAB_COLUMNS
WHERE VERSION = 604)
Ejemplo de UPDATE Multicolumna:
Menos Eficiente :
UPDATE EMP
SET EMP_CAT = (SELECT MAX(CATEGORY)
FROM EMP_CATEGORIES),
SAL_RANGE = (SELECT MAX(SAL_RANGE)
FROM EMP_CATEGORIES )
WHERE EMP_DEPT = 0020;
Más Eficiente:
UPDATE EMP
SET (EMP_CAT, SAL_RANGE) = (SELECT MAX(CATEGORY), MAX(SAL_RANGE)
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
FROM EMP_CATEGORIES)
WHERE EMP_DEPT = 0020;
FUNCTION Lookup_Hist_Type
(typ IN number) return varchar2
IS
tdesc varchar2(30);
CURSOR C1 IS
SELECT TYPE_DESC
FROM HISTORY_TYPE
WHERE HIST_TYPE = typ;
BEGIN
OPEN C1;
FETCH C1 INTO tdesc;
CLOSE C1;
return (NVL(tdesc, ’?’));
END;
FUNCTION Lookup_Emp
(emp IN number) return varchar2
IS
ename varchar2(30);
CURSOR C1 IS
SELECT ENAME
FROM EMP
WHERE EMPNO = emp;
BEGIN
OPEN C1;
FETCH C1 INTO ename;
CLOSE C1;
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
return (NVL(ename, ’?’));
END;
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Uso de Alias de Tabla
Por Ejemplo:
Menos Eficiente:
SELECT *
FROM EMP (Tabla Base)
WHERE EMPNO > 0
AND DEPTNO IN (SELECT DEPTNO
FROM DEPT
WHERE LOC = ‘STGO’)
Más Eficiente:
SELECT *
FROM EMP
WHERE EMPNO > 0
AND EXISTS (SELECT ‘X’
FROM DEPT
WHERE DEPTNO = EMP.DEPTNO
AND LOC = ‘STGO’)
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Uso de NOT EXISTS en lugar de NOT IN
En subconsultas como las siguientes, la cláusula NOT IN causa un
sort/merge interno. La cláusula NOT IN es la más lenta posible, ya que fuerza una
lectura completa de la tabla en la subconsulta. Trate de no usar NOT IN y reemplácela
con Outer JOINS o con un NOT EXISTS como se muestra a continuación:
SELECT . . .
FROM EMP
WHERE DEPT_NO NOT IN (SELECT DEPT_NO
FROM DEPT
WHERE DEPT_CAT = ‘A’);
Método 1 (Eficiente) :
SELECT . . .
FROM EMP A, DEPT B
WHERE A.DEPT_NO = B.DEPT_NO (+)
AND B.DEPT_NO IS NULL
AND B.DEPT_CAT(+) = 'A'
SELECT . . .
FROM EMP E
WHERE NOT EXISTS (SELECT ‘X’
FROM DEPT
WHERE DEPT_NO = E.DEPT_NO
AND DEPT_CAT = ‘A’);
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Uso JOINS en lugar del EXISTS
SELECT ENAME
FROM EMP E
WHERE EXISTS (SELECT ‘X’
FROM DEPT
WHERE DEPT_NO = E.DEPT_NO
AND DEPT_CAT = ‘A’);
SELECT ENAME
FROM DEPT D, EMP E
WHERE E.DEPT_NO = D.DEPT_NO
AND D.DEPT_CAT = ‘A’;
Por ejemplo:
Menos Eficiente:
Más Eficiente:
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
FROM DEPT D
WHERE EXISTS (SELECT ‘X’
FROM EMP E
WHERE E.DEPT_NO = D.DEPT_NO);
Para activar en forma global el SQL trace, se tiene que setear el parámetro
SQL_TRACE a TRUE en el init.ora. El parámetro USER_DUMP_DEST especifica el
directorio donde SQL trace escribe el archivo de trace.
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Uso de EXPLAIN PLAN para Analizar Instrucciones SQL
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Luego, se debe utilizar el siguiente script para ejecutar y ver el resultado
del Explain Plan. Se recomienda tener las instrucciones en un archivo con extensión
SQL.
set echo on
delete from plan_table
where statement_id = 'MI_QUERY';
commit;
COL operation FORMAT A30
COL options FORMAT A15
COL object_name FORMAT A20
EXPLAIN PLAN set statement_id = 'MI_QUERY' for
/* ------ Escriba su SQL Aqui ------*/
select *
from tabla
/*----------------------------*/
/
set echo off
select operation, options, object_name
from plan_table
where statement_id = 'MI_QUERY'
start with id = 0
connect by prior id=parent_id and prior statement_id =
statement_id;
set echo on
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Uso de Indices para mejorar la Performance
Un índice es una parte conceptual de una tabla de una base de datos que
puede ser usada para acelerar la recuperación de datos desde la tabla. Internamente,
ORACLE usa una sofisticada estructura de índice B-tree.
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Operaciones que usan Índices
Por ejemplo:
SELECT *
FROM LODGING
WHERE LODGING = ‘ROSE HILL’;
SELECT LODGING
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
FROM LODGING
WHERE LODGING = ‘ROSE HILL’;
Ejemplo:
SELECT LODGING
FROM LODGING
WHERE LODGING LIKE ‘M%’
Ejemplo:
SELECT LODGING
FROM LODGING
WHERE MANAGER = ‘BILL GATES’;
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Dado que la consulta selecciona la columna LODGING y la columna
LODGING no está en el índice LODGING$MANAGER, la Búsqueda por Rango de
Índice tiene que ser seguida por una operación de Acceso a Tablas a través de RowID.
Cuando se especifica una rango de valores para una columna, un índice
no será usado si el primer carácter especificado es un comodín. La siguiente consulta
no usará el índice LODGING$MANAGER:
SELECT LODGING
FROM LODGING
WHERE MANAER LIKE ‘%HANMAN’;
La Tabla Directiva es la tabla que será leída primero (usualmente vía una
operación de Acceso Completo a la Tabla). El método de selección para la tabla
directiva depende del optimizador en uso.
Si se está usando CBO, entonces el optimizador chequeará las
estadísticas para el tamaño de tablas y la selección de los índices y escogerá la ruta
con el coste total más bajo.
Si se está usando RBO, y existen índices que están disponibles para
todas las condiciones de JOIN, entonces la tabla directiva será usualmente la que esté
listada al final de cláusula FROM.
Por Ejemplo:
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Deshabilitando Explícitamente un Índice
Por Ejemplo:
SELECT ENAME
FROM EMP
WHERE EMPNO = 7935
AND DEPTNO + 0 = 10
AND EMP_TYPE || ‘’ = ‘A’;
SELECT ENAME
FROM EMP
WHERE EMP_TYPE = ‘A’
AND EMP_CLASS = ‘X’;
Nota : Las funciones SQL MIN y MAX son excepciones a esta regla y utilizarán todos
los índices disponibles.
Por Ejemplo:
Menos Eficiente:
SELECT . . .
FROM DEPT
WHERE SAL * 12 > 25000;
Más Eficiente:
SELECT . . .
FROM DEPT
WHERE SAL > 25000 / 12;
Por Ejemplo:
SELECT ENAME
FROM EMP
WHERE EMPNO = 2362
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
AND DEPTNO = 20;
Por ejemplo:
SELECT . . .
FROM DEPT
WHERE DEPT_CODE NOT = 0;
SELECT . . .
FROM DEPT
WHERE DEPT_CODE > 0;
SELECT *
FROM EMP
WHERE DEPTNO >= 4
En vez de
SELECT *
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
FROM EMP
WHERE DEPTNO > 3
En vez de:
WHERE KEY1 = 10
AND (KEY1 NOT = 10 AND KEY2 = 20)
Por Ejemplo:
SELECT . . .
FROM DEPARTMENT
WHERE DEPT_CODE IS NOT NULL;
SELECT . . .
FROM DEPARTMENT
WHERE DEPT_CODE >= 0;
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
columnas no principales del índice, entonces el índice no será usado para resolver la
consulta.
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
Uso de UNION ALL en lugar de UNION (Cuando sea Posible)
Por Ejemplo:
Menos Eficiente:
Más Eficiente:
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile
WHERE TRAN_DATE = ‘31-DEC-95’
Huérfanos 835 piso 20 oficina 2003, Fonos: * 6322497- *6322102, Fax: 6322529 - www.ciisa.cl
Santiago Chile