performance - rapidas - optimizar inner join sql server
Las 5 consultas SQL que más tiempo consumen en Oracle (8)
Depende de qué versión de Statspack tengas, para 9i y debajo Statspack es lo que buscas, 10g y superior, quieres una awr , estas dos herramientas te darán los mejores sql y muchas otras cosas.
¿Cómo puedo encontrar consultas SQL de bajo rendimiento en Oracle?
Oracle mantiene estadísticas sobre el área SQL compartida y contiene una fila por cadena SQL (v $ sqlarea). Pero, ¿cómo podemos identificar cuál de ellos está funcionando mal?
Encontré que esta declaración SQL es un lugar útil para comenzar (lo siento, no puedo atribuir esto al autor original, lo encontré en algún lugar en Internet):
SELECT * FROM
(SELECT
sql_fulltext,
sql_id,
elapsed_time,
child_number,
disk_reads,
executions,
first_load_time,
last_load_time
FROM v$sql
ORDER BY elapsed_time DESC)
WHERE ROWNUM < 10
/
Encuentra las sentencias SQL superiores que están almacenadas actualmente en el caché de SQL ordenado por el tiempo transcurrido. Las declaraciones desaparecerán de la memoria caché con el tiempo, por lo que no sería bueno intentar diagnosticar el trabajo por lotes de la noche anterior cuando ingrese al trabajo al mediodía.
También puede intentar ordenar por disk_reads y ejecuciones. Las ejecuciones son útiles porque algunas aplicaciones deficientes envían la misma instrucción SQL demasiadas veces. Este SQL supone que usa variables de vinculación correctamente.
Luego, puede tomar el sql_id
y el child_number
de una declaración y alimentarlos a este bebé:
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR(''&sql_id'', &child));
Esto muestra el plan real del caché de SQL y el texto completo del SQL.
Hay varias formas posibles de hacerlo, pero tiene un google para tkprof
No hay GUI ... es completamente de línea de comando y posiblemente un toque intimidante para los principiantes de Oracle; pero es muy poderoso.
Este enlace parece un buen comienzo:
La siguiente consulta devuelve instrucciones SQL que realizan un gran número de lecturas de disco (también incluye al usuario infractor y la cantidad de veces que se ha ejecutado la consulta):
SELECT t2.username, t1.disk_reads, t1.executions,
t1.disk_reads / DECODE(t1.executions, 0, 1, t1.executions) as exec_ratio,
t1.command_type, t1.sql_text
FROM v$sqlarea t1, dba_users t2
WHERE t1.parsing_user_id = t2.user_id
AND t1.disk_reads > 100000
ORDER BY t1.disk_reads DESC
Ejecute la consulta como SYS y ajuste el número de lecturas de disco según lo que considere excesivo (100.000 trabajos para mí).
Recientemente utilicé esta consulta para rastrear a los usuarios que se niegan a aprovechar Explain Plans
antes de ejecutar sus declaraciones.
Encontré esta consulta en un libro de ajuste de Oracle SQL antiguo (que desafortunadamente ya no tengo), así que disculpas, pero no atribución.
Mientras buscaba recibí la siguiente consulta que hace el trabajo con una suposición (tiempo de ejecución de la consulta> 6 segundos)
SELECCIONAR nombre de usuario, sql_text, sofar, totalwork, units
FROM v $ sql, v $ session_longops
WHERE sql_address = dirección AND sql_hash_value = hash_value
ORDER BY dirección, hash_value, child_number;
Creo que la consulta anterior mostrará una lista de los detalles para el usuario actual.
Los comentarios son bienvenidos!
Puede encontrar escaneos de tabla completa intensivos en disco con algo como esto:
SELECT Disk_Reads DiskReads, Executions, SQL_ID, SQL_Text SQLText,
SQL_FullText SQLFullText
FROM
(
SELECT Disk_Reads, Executions, SQL_ID, LTRIM(SQL_Text) SQL_Text,
SQL_FullText, Operation, Options,
Row_Number() OVER
(Partition By sql_text ORDER BY Disk_Reads * Executions DESC)
KeepHighSQL
FROM
(
SELECT Avg(Disk_Reads) OVER (Partition By sql_text) Disk_Reads,
Max(Executions) OVER (Partition By sql_text) Executions,
t.SQL_ID, sql_text, sql_fulltext, p.operation,p.options
FROM v$sql t, v$sql_plan p
WHERE t.hash_value=p.hash_value AND p.operation=''TABLE ACCESS''
AND p.options=''FULL'' AND p.object_owner NOT IN (''SYS'',''SYSTEM'')
AND t.Executions > 1
)
ORDER BY DISK_READS * EXECUTIONS DESC
)
WHERE KeepHighSQL = 1
AND rownum <=5;
Puede tomar el promedio de buffer que obtiene por ejecución durante un período de actividad de la instancia:
SELECT username,
buffer_gets,
disk_reads,
executions,
buffer_get_per_exec,
parse_calls,
sorts,
rows_processed,
hit_ratio,
module,
sql_text
-- elapsed_time, cpu_time, user_io_wait_time, ,
FROM (SELECT sql_text,
b.username,
a.disk_reads,
a.buffer_gets,
trunc(a.buffer_gets / a.executions) buffer_get_per_exec,
a.parse_calls,
a.sorts,
a.executions,
a.rows_processed,
100 - ROUND (100 * a.disk_reads / a.buffer_gets, 2) hit_ratio,
module
-- cpu_time, elapsed_time, user_io_wait_time
FROM v$sqlarea a, dba_users b
WHERE a.parsing_user_id = b.user_id
AND b.username NOT IN (''SYS'', ''SYSTEM'', ''RMAN'',''SYSMAN'')
AND a.buffer_gets > 10000
ORDER BY buffer_get_per_exec DESC)
WHERE ROWNUM <= 20
la información completa que recibí de askTom-Oracle. Espero que te ayude
select *
from v$sql
where buffer_gets > 1000000
or disk_reads > 100000
or executions > 50000