Ola,

Em um sistema, tenho as tabelas de nota_fiscal (NF) e produto_nota_fiscal (PNF), para os itens da nota. Ha um indice em pnf para a PK da nota fiscal. O problema eh que eu precisaria que este indice fosse utilizado mais vezes. O volume de dados que tenho eh:

NF:   2.061.771
PNF: 12.440.536

Porem eu precisaria que este indice fosse mais utilizado. Ao pesquisar dados de um dia o indice eh utilizado, porem para mais de um dia estah acontecendo uma custosa busca sequencial em PNF. Utilizei para teste os dias 05 e 06/04/06. No dia 05, temos 1638 notas e o indice eh utilizado. Porem para os dois dias, com 2780 o indice deixa de ser utilizado. Os valores representam respectivamente 0,013166635 e 0,22346304 % dos registros de PNF. O indice nao deveria ser utilizado em ambos os casos?

Como posso verificar porque um indice eh utilizado ou nao?

Abaixo a consulta e os explains:

EXPLAIN
SELECT 1
FROM nota_fiscal nf
    JOIN produto_nota_fiscal pnf USING (cd_nota_fiscal)
WHERE nf.dt_emissao >= '2006-04-05'
 AND nf.dt_emissao <= '2006-04-05'

foo=> \i teste.sql
QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------
Nested Loop  (cost=0.00..2525.90 rows=6 width=0)
-> Index Scan using idx_nota_fiscal_dt_emissao on nota_fiscal nf (cost=0.00..8.46 rows=1 width=4) Index Cond: ((dt_emissao >= '2006-04-05'::date) AND (dt_emissao <= '2006-04-05'::date)) -> Index Scan using idx_produto_nota_fiscal_cd_nota_fiscal on produto_nota_fiscal pnf (cost=0.00..2509.18 rows=661 width=4)
        Index Cond: (nf.cd_nota_fiscal = pnf.cd_nota_fiscal)
(5 registros)

Tempo: 135,532 ms
foo=> \i teste.sql
QUERY PLAN ------------------------------------------------------------------------------------------------------------------
Hash Join  (cost=1530.24..391540.26 rows=5392 width=0)
  Hash Cond: (pnf.cd_nota_fiscal = nf.cd_nota_fiscal)
-> Seq Scan on produto_nota_fiscal pnf (cost=0.00..343462.89 rows=12398189 width=4)
  ->  Hash  (cost=1519.02..1519.02 rows=898 width=4)
-> Index Scan using idx_nota_fiscal_dt_emissao on nota_fiscal nf (cost=0.00..1519.02 rows=898 width=4) Index Cond: ((dt_emissao >= '2006-04-05'::date) AND (dt_emissao <= '2006-04-06'::date))
(6 registros)

Tempo: 177,220 ms
foo=> SELECT COUNT(*) FROM nota_fiscal WHERE dt_emissao >= '2006-04-05' AND dt_emissao <= '2006-04-05';
count
-------
 1638
(1 registro)

Tempo: 672,419 ms
foo=> SELECT COUNT(*) FROM nota_fiscal WHERE dt_emissao >= '2006-04-05' AND dt_emissao <= '2006-04-06';
count
-------
 2780
(1 registro)

Alvaro
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a