Pular para o conteúdo

Verificando consultas perniciosas

Verificando consultas perniciosas

Diversas vezes, em todos os lugares por onde ando, me deparo com consultas que são extremamente perniciosas ao sistema. Aquelas consultas que demoram demais, consomem muita CPU, memória ou acesso a disco.
Às vezes a consulta em si é rápida, mas é executada inúmeras vezes e, no conjunto da obra, acaba sendo um problema para a aplicação, já peguei situações em que uma aplicação fazia consulta ao sysdate do banco para mostrar o relógio na tela, quando seria muito mais simples, e menos penoso, usar uma funcionalidade da própria aplicação sem ter que ficar consultando a cada segundo o banco de dados…
Esta consulta poderá mostrar, primeiramente as queries que trazem consultas full table scan, mas a partir dela você conseguirá obter muitas outras informações interessante como I/O, uso de memória, cardinalidade, custo, número de vezes que é executada entre outras coisas… A sua imaginação é o limite…

SQL
Select s.address, s.last_load_time, s.first_load_time, TO_CHAR ((s.cpu_time / s.executions) / 1000, '999,999,999.9999') tempo_cpu, TO_CHAR ((s.elapsed_time / s.executions) / 1000, '999,999,999.9999') tempo_decorrido, s.executions, p.object_owner, p.object_name, p.cost, p.cardinality, p.bytes, p.io_cost, p.filter_predicates, w.active_time, w.estimated_optimal_size, w.last_memory_used, w.total_executions, w.active_time
From v$sql_plan p, v$sql s, v$sql_workarea w
Where p.address = s.address
And p.address = w.address (+)
And p.hash_value = w.hash_value (+)
And p.id = w.operation_id (+)
And p.options = 'FULL'
And p.object_owner not like '%SYS%'
And SUBSTR (last_load_time, 1, 10) = TO_CHAR (sysdate, 'yyyy-mm-dd')
-- And (p.cardinality > 100
-- or p.cost > 50)
And p.filter_predicates is not null
And s.executions > 1
And (s.elapsed_time / 1000) > 1
Order by tempo_decorrido desc --(cost + cardinality) desc

Uma ferramenta que vai te auxiliar a pegar a consulta completa é a seguinte…

SQL
Select sql_text from v$sqltext where address = 'pego da consulta anterior' order by piece;

Já que abri a caixinha de ferramentas :

SQL
select p.hash_value, operation, options, object_name name, TRUNC (bytes / 1048576) "input(MB)", TRUNC (last_memory_used / 1024) last_mem, TRUNC (estimated_optimal_size/1024) opt_mem, TRUNC (estimated_onepass_size/1024) onepass_mem, DECODE (optimal_executions, null, '-', optimal_executions||'/'||onepass_executions||'/'||multipasses_executions) "O/1/M"
from v$sql_plan p, v$sql_workarea w
where p.address = w.address (+)
And p.hash_value = w.hash_value (+)
And p.id = w.operation_id (+)
And p.address = 'também da primeira consulta';

Acho que isso vai ajudar alguns 😀

Marcio68Almeida

Marcio68Almeida

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Marcações:
plugins premium WordPress