sábado, 6 de agosto de 2011

TIP'S PARA EL TUNING DE TU SQL

En ocasiones no solo basta con realizar un buen afinamiento a la base de datos Oracle para mejorar el rendimiento.  Podemos hacer que mejore el rendimiento aplicando buenas prácticas al realizar nuestros SQL y PL/SQL.

A continuación les indicaré unos tips que pueden usar para las buenas prácticas en el desarrollo.

USAR VARIABLES BIND:

Esto es sobre todo en aplicaciones desarrollo de aplicaciones JAVA, .NET, VSB6, VFP, PHP, Etc. Ya que la las herramientas developer de Oracle no ocurre mucho.

Para esto primero entendamos que:

·         El análisis de una sentencia SQL y averiguar su plan de ejecución óptimo consumen mucho tiempo para Oracle, por eso Oracle mantiene las sentencias SQL en memoria después de haber analizado y ejecutado la sentencia SQL para reutilizar no realizar de nuevo el análisis y usar el plan de ejecución definidos en su primera ejecución.
·         Oracle antes de realizar el análisis primero busca la librería SQL el contexto (SGA) para ver si hay una declaración idéntica existente.
·         Para que una sentencia SQL sea compartida debe de ser idéntica en todo sentido de la palabra.

Veamos un ejemplo,
·     Aunque las siguientes sentencias hagan lo mismo no son iguales, ya que el analizador es sensible a las mayúsculas y minúsculas:
Select * from empleados where numero_empleado=2012;
SELECT * FROM EMPLEADOS WHERE NUMERO_EMPLEADO=2012;

·     Las dos sentencias SQL no son idénticas ya que el filtro en el campo NUMERO_EMPLEADO son diferentes, por lo que durante su ejecución las dos sentencias se analizaran y planificaran como diferentes:
SELECT * FROM EMPLEADOS WHERE NUMERO_EMPLEADO=2012;
SELECT * FROM EMPLEADOS WHERE NUMERO_EMPLEADO=2013;

·     Para optimizar la ejecución de estas dos sentencias debemos usar en lo posible las variables bind
SELECT * FROM EMPLEADOS WHERE NUMERO_EMPLEADO=:NUM_EMP;

Si desean pueden ver mas a fondo de este tema con ejemplos en el siguiente link 

USAR WHERE EN VEZ DE HAVING:
El evitar el uso del HAVING en la instrucción SELECT. Las condiciones del HAVING son de exclusividad para funciones agregadas como el COUNT, SUM, AVG, MAX, MIN, etc y no son para condiciones de datos.

·    Si usamos el HAVING se extraerán todos los datos y luego se realizara el agrupamiento con el filtrado de los datos.

SELECT OWNER,OBJECT_TYPE, COUNT(*)
FROM ALL_OBJECTS
GROUP BY OWNER,OBJECT_TYPE
HAVING OWNER='SYSTEM';
·     En cambio con el WHERE se filtran los datos y luego se realice el agrupamiento, siendo esto menos costoso.

SELECT OWNER,OBJECT_TYPE, COUNT(*)
FROM ALL_OBJECTS
WHERE OWNER='SYSTEM'
GROUP BY OWNER,OBJECT_TYPE;


USAR UNION ALL EN VEZ DEL UNION
·     Con la clausula UNION se realizará un ordenamiento para obtener  filas distintas y eliminar las repetidas, un ordenamiento es un costo adicional en el procesamiento de la CPU.
SELECT *
FROM ALL_TABLES
UNION
SELECT *
FROM DBA_TABLES;


·     Con la clausula UNIOM ALL no se realiza ordenamiento ni eliminación de las filas repetidas, lo que hace es unir tal como vengan los datos de las sub-consultas.
SELECT *
FROM ALL_TABLES
UNION ALL
SELECT *
FROM DBA_TABLES


USAR EXISTS O NOT EXISTS EN VEZ DE IN O NOT IN
Es mejor usar la clausula EXISTS en vez del IN, esto ya que al usar el EXISTS es como si realizaramos el JOIN entre las tablas. El uso de la clausula IN es recomendable si el dominio de datos es pequeño (a mi criterio que no pase de 100 registros).

·         Veamos el ejemplo con el NOT IN.
SELECT * FROM ALL_OBJECTS
WHERE OBJECT_ID NOT IN (SELECT OBJECT_ID
                        FROM USER_OBJECTS);


·         Veamos el ejemplo con el NOT EXISTS.
SELECT * FROM ALL_OBJECTS A
WHERE NOT EXISTS (SELECT 1 FROM USER_OBJECTS B
                  WHERE A.OBJECT_ID=B.OBJECT_ID );


No hay comentarios:

Publicar un comentario