> Essa é a chave da tabela:
> pk_tb_matricula PRIMARY KEY(matr , cursocod , gradecod , disccodof , periodo
> , ano );
> 
> Esses são os 2 índices que fizeram diferença na execução da consulta do
> programa:
> CREATE INDEX turma_teo
> ON tb_matricula
> USING btree
> (turmateo COLLATE pg_catalog."default" , ano , periodo );
> 
> CREATE INDEX turmapra_idx
> ON tb_matricula
> USING btree
> (turmapra COLLATE pg_catalog."default" , ano , periodo );
> 
> Esta é a consulta complicada:
> O problema é que o programa faz um FOR nesta consulta, pois é um count de
> cada turma.
> 
> explain analyze SELECT COUNT(*)
> FROM TB_MATRICULA
> WHERE DISCCODOF= 'ADM082' AND
> LOCALCOD = 'C01' AND
> ((REGIME = 'A' AND ANO = 2012) OR
> (REGIME !='A' AND ANO = 2012 AND PERIODO = 1)) AND
> (TURMATEO = 'X') OR
> ('TURMAPRA = 'Y'));
> 
> Esse foi o resultado do Explain:
> "Aggregate (cost=4835.89..4835.90 rows=1 width=0) (actual time=39.486..39.486
> rows=1 loops=1)"
> " -> Index Scan using pk_tb_matricula on tb_matricula (cost=0.00..4835.02
> rows=351 width=0) (actual time=0.190..39.231 rows=1520 loops=1)"
> " Index Cond: (((disccodof)::text = 'ADM082'::text) AND (ano = 2012))"
> " Filter: ((localcod = 'C01'::bpchar) AND (((turmateo)::text = '1'::text) OR
> ((turmapra)::text = ''::text)) AND ((regime = 'A'::bpchar) OR ((regime <>
> 'A'::bpchar) AND (periodo = 1))))"
> "Total runtime: 39.591 ms"

Bom, veja seu plano de execução:
A consulta usou apenas o índice da chave primária (pg_tb_matricula).
A consulta levou pouco mais de 39 ms para executar, obteve uma linha agregando 
4835 (por causa do count) e fim, dentre 
Portanto, os índices turmapra_idx e turma_teo, para essa consulta em 
específico, não estão sendo utilizados.

Considere removê-los e veja se o plano de execução muda (faça outro EXPLAIN 
ANALYZE sem os índices).
Se o plano *não* mudar (não deve mudar, porque o índice usado foi o da pk), 
simplesmente fique sem os índices exceto a própria chave primária. Claro que 
não estou considerando outras consultas que você pode ter em seu sistema.

39 ms me parece um tempo excelente para execução de uma consulta com count(*).
Você disse que faz um laço em seu programa (for) e executa a consulta várias 
vezes. Quantas vezes?
Não dá pra trocar o laço por uma consulta mais elaborada e deixar o banco de 
dados fazer isso por você?

Outra coisa interessante, qual versão do PostgreSQL está usando?
Na versão 9.2.x você tem o recurso index_only_scan que pode melhorar o 
desempenho dessa consulta em umas... 10 ou 12 vezes. Não que você precise 
disso, claro.

[]s

__________________________________
Flavio Henrique A. Gurgel
Líder de Projetos Especiais
Consultoria, Projetos & Treinamentos 4LINUX
Tel1: +55-11.2125-4747 ou 2125-4748
www.4linux.com.br
email: [email protected]
______________________________
FREE SOFTWARE SOLUTIONS
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a