¿Qué elementos de una consulta consumen más recursos de tiempo y CPU?

Hola .
Mi duda es la siguiente:
Como puedo saber que elementos de una consulta consumen más recursos (tiempo y CPU). Esto me gustaría conocerlo para poder tomar buenas decisiones al momento de lanzar querys muy pesados sobre Bases de Datos muy atareadas.
¿Por ejemplo cuesta más un IN que un OR? Cuaste mucho las conversiones to_char, to_date, to_number?
Espero haberme explicado.
Muchas Gracias desde Saltillo Coahuila

1 Respuesta

Respuesta
1
En primer lugar, debes saber que tipo de optimización tienes en tu Db. Existen 3, por regla, por costo o por selección. el default es por seleccion. Este es el que va a utilizar cada vez que le des un analyze a tus tablas.
Si vas a utilizar por regla, evalúa posibles caminos de ejecución en base a reglas sintácticas.
El de Costo utiliza las estadísticas de los objetos para buscar el mejor camino de ejecución, para ello es necesario que se ejecute periódicamente el comando analyze sobre tablas e índices.
Existen 2 formas de saber el consumo una con el PLAIN_TABLE que es el plan de ejecución y te da el costo, y otra con el Trace. Que ahí te da más información.
Si estas utilizando como optimización Regla, tené en cuenta que la tabla con menos cantidad de registros debe ser la última de from, ya que Oracle lee la instrucción de la derecha a la izquierda.
Si son más de dos tablas la tabla más a la derecha debe ser la tabla de intersección, o sea, la tabla de la cual dependen más tablas.
En el caso de cualquier Select debes de evitars ante todo el uso del select *, ya que consume mucho tiempo del servidor, debido a que el parseador debe obtener la información de cada columna del diccionario.
Otro tip, al momento de seleccionar datos de una tabla, es más eficiente filtrar por medio del where y no por Having. Utilizar Exists en lugar de IN. En el where la condición que filtre más registros debe ir más a la derecha (último).
Trata la manera de nunca utilizar % al principio de la condición.
Para saber o identificar que querys tienen bajo rendimiento podes correr este script:
SELECT EXECUTIONS, DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_Ratio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_Per_Run, SQL_TEXT
FROM V$SQLAREA
WHERE EXECUTIONS > 0
AND BUFFER_GETS > 0
AND (BUFFER_GETS - DISK_READS) / BUFFER_GETS < 0.80
ORDER BY 4 DESC
¿El tipo de optimización en la bd esta fijo para todas las transacciones o puedo seleccionar un tipo de optimización de acuerdo al query o a la sesión abierta?
¿Conoces algún documento donde pueda obtener mayor detalle sobre la configuración de las optimizaciones?
No he utilizado el trace, por lo que me gustaría también leer al respecto...
Te agradezco mucho la ayuda, me ha sido muy útil hasta el momento...
Saludos
El tipo de optimización esta fijo en la DB, como te decía el default es CHOSSE (selección).
Cuando estas ejecutando algun query, podes decidir que optimizador utilizar, colocando /*+rule*/ o /*+cost*/ despues del select por ejemplo
select /*+rule*/ nomemp from emp;
quiere decir que vas a utilizar regla (/*+rule*/).
o bien con un alter session set OPTIMIZER_MODE = { all_rows | first_rows | rule | choose }
Esto lo podes encontrar en la ayuda de Oracle en Oracle8i SQL Reference en www.lazydba.com
Con respecto al TRACE, recordate que es para alguna sesión en particular, lo tienes que correr con el sys y es:
Begin
DBMS_SYSTEM.SET_EV(<sid>,<serial#>,10046,<nivel>,'');
commit; )
end;
Donde nivel puede ser 1,4,8,12 dependiendo que quieres que te aparezca, el 8 es para que te registre los querys con bind variables, el 12 para que sea con los valores que lleva en ese momento. Esto te genera un archivo trace (. Trc)
El script para generar y para ver donde esta el archivo y que estas monitoreando es:
select 'ora_'||p.spid||'_'||lower(instance_name)||'.trc' archivo, 'SID=('|| s.sid || '.' || s.serial# || ') USR: ' || s.username || ' OSUser: ' || s.osuser || ' Term: ' || s.terminal sesion, 'begin DBMS_SYSTEM.SET_EV('||s.sid||','||s.serial#||',10046,8,'||''''||''''||'); commit; end;' cmd_trace from v$session s, v$process p, v$instance i where p.addr = s.paddr and s.username in ('<login usuario>')

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas