CodeGym /Cursos /SQL SELF /Análise de queries lentas com pg_stat_statements

Análise de queries lentas com pg_stat_statements

SQL SELF
Nível 45 , Lição 4
Disponível

Quando você tá trampando em projetos reais, milhares de usuários podem estar mexendo no seu app ao mesmo tempo. Eles mandam queries pro banco, adicionam dados, leem, atualizam... E aí você percebe que seu servidor começa a "chorar". Isso é um sinal de que suas queries tão longe de serem otimizadas. Às vezes aquela query que parecia de boa "no papel" pode virar um desastre pra sua performance. É aí que entra o pg_stat_statements na jogada.

pg_stat_statements te permite:

  1. Monitorar queries lentas.
  2. Sacar quantas vezes cada query foi executada.
  3. Ver quanto tempo elas gastaram.
  4. Ver o tempo médio de execução da query.
  5. Evitar o erro fatal de reescrever o app inteiro!

Explorando a estrutura do pg_stat_statements

Depois de ativar a extensão, aparece uma view especial no seu banco chamada pg_stat_statements. Lá ficam todos os dados das queries executadas. Bora ver o que tem nela:

SELECT * FROM pg_stat_statements LIMIT 1;

O resultado pode ser assim (versão simplificada):

query calls total_time rows shared_blks_read
SELECT * FROM students 500 20000 ms 5000 100

Explicação rápida:

  • query — a própria query SQL.
  • calls — quantas vezes essa query rodou.
  • total_time — quanto tempo, no total, a query gastou.
  • rows — quantas linhas a query retornou.
  • shared_blks_read — quantos blocos foram lidos (vai pro disco se não tiver no cache).

Analisando os resultados

Agora que o pg_stat_statements tá ligado, bora ver como achar as queries lentas.

As queries mais lentas

Pra descobrir quais queries tão gastando mais tempo, usa essa query aqui:

SELECT query, total_time, calls, mean_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 5;

Aqui:

  • mean_time — é o tempo médio de execução de cada query (total_time / calls).
  • ORDER BY total_time DESC — ordena pelo tempo total gasto.

Queries que rodam toda hora

Às vezes o problema não é a query ser lenta, mas sim rodar vezes demais. Tipo assim:

SELECT query, calls
FROM pg_stat_statements
ORDER BY calls DESC
LIMIT 5;

Otimizando queries

  1. Use indexação

Se você vê que queries em certas colunas tão lentas, confere se tem índice nessas colunas. Por exemplo, se você tem uma tabela students com um monte de linhas, e sempre consulta o campo last_name, vale criar um índice:

CREATE INDEX idx_students_last_name ON students (last_name);
  1. Reescreva a query

Imagina que você vê uma query tipo SELECT * FROM orders WHERE amount > 1000 demorando demais. Provavelmente, ao invés de pegar "tudo de tudo", é melhor buscar só as colunas que precisa:

SELECT order_id, amount FROM orders WHERE amount > 1000;

Limpando as estatísticas

Às vezes, pra ver só os resultados novos (tipo depois de otimizar algo), você precisa limpar os dados do pg_stat_statements. Faz assim:

SELECT pg_stat_statements_reset();

Funciona tipo o botão "Resetar" da sua calculadora. Depois disso, as estatísticas começam do zero.

Caçando queries problemáticas

Imagina que você é admin do banco de dados de uma universidade, e a galera tá reclamando que o portal do aluno tá carregando devagar demais. Você decide checar o pg_stat_statements:

Passo 1: Achar as queries mais lentas

SELECT query, total_time, calls, mean_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 1;

Você vê que uma query tipo SELECT * FROM students WHERE status = 'active' tá levando 30 segundos. Caraca. Precisa resolver isso já.

Passo 2: Checar indexação Analisando a tabela students, você percebe que a coluna status não tem índice. Bora corrigir:

CREATE INDEX idx_students_status ON students (status);

Passo 3: Conferir o resultado Depois de otimizar, você olha de novo o pg_stat_statements e vê que a query agora roda em 0.5 segundo. Sucesso!

Erros comuns usando pg_stat_statements

Às vezes os admins dão umas vaciladas na hora de analisar as queries:

  1. Extensão não ativada. Se você esqueceu de colocar o pg_stat_statements no shared_preload_libraries, não vai rolar estatística nenhuma.
  2. Ignorar indexação. Mesmo se as queries tão lentas, às vezes só falta criar o índice certo.
  3. Não resetar as estatísticas. Se você não roda o pg_stat_statements_reset(), os dados antigos atrapalham a análise do que tá rolando agora.

Usar o pg_stat_statements no seu trampo é tipo ter um GPS pro banco de dados: ele mostra exatamente onde você tá preso no "engarrafamento" e ainda dá umas dicas de como desviar. Se configurar direitinho, esse recurso pode turbinar a performance do seu banco de dados.

1
Pesquisa/teste
Monitoramento do PostgreSQL, nível 45, lição 4
Indisponível
Monitoramento do PostgreSQL
Monitoramento do PostgreSQL
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION