Olá comunidade, peço ajuda de vocês mais uma vez -
Não sei mais como melhorar o desempenho. Por favor, me ajudem.
### CENÁRIO
Preciso otimizar uma consulta que faz complexos cálculos em grandes conjuntos
de dados.
Tenho que chamar a função fs_disponibilidade_barras_diario [1] fornecendo
o identificador do equipamento (barra) e data em questão.
Se chamar a função com barra com o valor -1, então a função vai calcular a
disponibilidade para todos os equipamentos (11 no total).
O problema é que apenas pra um dia, a função está demorando + ou - 45 minutos,
e meu chefe quer um relatório mensal (fs_disponibilidade_barras_mensal [2] )
para todas as barras; do jeito que está, isso levaria 23 horas. Já li vários
materiais e
links sugeridos por vocês na lista e já otimizei o SQL o quanto pude,
principalmente
as funções [3] e [4]. Depois de otimizar os sql's [3] e [4] (estava muito mais
lento antes),
partir então para os parâmetros de configuração e fiz as alterações mostradas
em [X].
Novamente o tempo continuou o mesmo.
A consulta já terminou há muito tempo e o cache de disco está até agora
ocupando 96% da memória livre.
Eis as configurações da memória depois da execução de
fs_disponibilidade_barras_diario [1] pra o dia 2009-02-01.
*** Logo após reiniciar o sistema e exatamente antes de executar [1] para o dia
2009-02-02
Memória física total - 7.92 GB
Memória física livre - 7.46 GB
Memória compartilhada - 0.00 KB
Buffers de disco - 21.11 MB
Cache de disco - 279.75 MB
Memória swap total - 15.72 GB
Memória swap livre - 15.72 GB
*** Depois de executar [1]
Memória física total - 7.92 GB
Memória física livre - 33.76 MB
Memória compartilhada - 0.00 KB
Buffers de disco - 16.84 MB
Cache de disco - 7.63 GB
Memória swap total -15.72 GB
Memória swap livre - 15.72 GB
O mais interessante é que a consulta diária acabou e o cache de disco + buffers
de disco
estão ocupando a memória quase toda e não foram liberados.
Não sei se isso é normal ou não.
Para se ter uma idéia, eis a quantidade de registros para cada barra para
apenas um dia (data=01/02/2009):
SELECT id_barra, count(*) from "DTF_TENSAO_BARRAS" where CAST(data_hora AS
DATE)='2009-02-01' group by id_barra;
"LIMC401M0VBV" 6133
"CH_B2T1_MES-32" 1395
"PRTF601VVA4" 527
"IZIA401M0VBV" 6213
"LIIT401M0VBV" 6069
"PDTF601VBV4" 6179
"LDBR604M0VBN" 5288
"MR2_BP401VBV" 524
"MR2_BP501VBV" 601
"PFBR501MVFBV" 265
"PFCL401MVFBV" 6305
Talvez um dos problemas é que a função fs_calcular_detalhes_dtf_tipo2 [4]
precisa ordernar
cada um desses conjuntos de registros pelos campos id_barra e data_hora
(preciso dos registros ordernados por esses campos para que o cálculo saia
correto).
Acho que ordernar 06 mil registros para uma barra pode aumentar muito o tempo e
consumo de memória.
Mais o cálculo diário precisa fazer isso pra 11 barras e o mensal tem q fazer a
mesma coisa só que pra 30 ou 31 dias;
sql = SELECT * FROM "DTF_TENSAO_BARRAS" WHERE CAST("data_hora" AS DATE) =
'2009-02-03' ORDER BY id_barra, "data_hora" ASC
FOR record_dtf_tensao_barras IN EXECUTE sql LOOP
<< CALCULOS >>
END LOOP;
###PERGUNTAS
1) Tem mais alguma configuração a ser feita no postgresql.conf que vocês
recomendam que eu faça ?
2) Você recomendam fazer alguma alteração a nível de sql em alguma
função, principalmente as funções [3] e [4] ?
3) É normal o cache de disco ficar lotado depois do termino da consulta ?
Se não for, como liberar esse espaço depois da execução de [3] e [4] via
plpgsql ?
PS: não sei nada sobre a teoria de índices (ainda vou começar a estudar essa
parte).
Estou mando em anexo, vários arquivos: postgresql.conf,
todas as tabelas e funções que utilizo, as função [3] e [4] comentadas com
minhas dúvidas principais,
EXPLAIN ANALYSE que fiz ontem no banco e o relatório de estatísticas das
tabelas feitas pelo pgAdmin.
Já foram feitos o cálculos para 15 dias, ou seja, as tabelas
"DTF_TENSAO_BARRAS", "DTF_BARRAS_DETALHES", "DISPONIBILIDADE_EQ" tem dados de
15 dias.
### CARACTERISTICAS HARWARE & SOFTWARE
Sistema Operacional CentOS 4.5
SGBD Postgresql 8.2.4
Processador Xeon FC-LGA 771 dual core Cache L2 4MB e Memória RAM de 7.92 GB.
É um servidor dedicado de banco de dados e servidor Web.
### POSTGRESQL.CONF [X]
Shared_buffer = 768 MB
Work_men = 256 MB
Maintenance_work_mem = 768 MB
Effective_cache_size = 1280 MB
Random_page_cost = 3.0
Max_fsm_pages = 800000
Max_fsm_relations = 2000
Fsync = OFF
Wal_buffer = 64
Checkpoint_segments = 16
### TABELAS e FUNÇÕES
[1] fs_disponibilidade_barras_diario(barra character varying, data date,
tolerancia integer)
[2] fs_disponibilidade_barras_mensal(barra character varying, mes integer, ano
integer, tolerancia integer)
[3] fs_calcular_detalhes_dtf_tipo1 (barra character varying, data date) (EM
ANEXO)
[4] fs_calcular_detalhes_dtf_tipo2 (barra character varying, data date,
tolerancia integer) (EM ANEXO)
<html>
<body>
<font face = "arial" size = "1" color = "#000080">Aviso:<br>"O emitente desta
mensagem é responsável por seu conteúdo e
endereçamento. Cabe ao destinatário cuidar quanto ao tratamento
adequado. Sem a devida autorização, a divulgação, a
reprodução, a distribuição ou qualquer outra
ação em desconformidade com as normas internas da ELETRONORTE S/A
são proibidas e passíveis de sanção disciplinar,
cível e criminal. Esta mensagem pode ser monitorada".
</font>
</body>
</html>_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral