PostgreSQL: COUNT (*) usa uma varredura seqüencial, não index

12

Por que o PostgreSQL varre sequencialmente a tabela em COUNT(*)busca de consulta, enquanto há uma chave primária indexada e muito pequena?

Adam Matan
fonte

Respostas:

15

As páginas wiki oficiais dão uma resposta para isso:

[...] A razão pela qual isso é lento está relacionada à implementação do MVCC no PostgreSQL. O fato de várias transações poderem ver estados diferentes dos dados significa que não pode haver uma maneira direta de "COUNT (*)" resumir os dados em toda a tabela; O PostgreSQL deve percorrer todas as linhas, em algum sentido. Isso normalmente resulta em uma varredura seqüencial, lendo informações sobre todas as linhas da tabela. [...]

Além disso, você pode tentar um ANALYZE para recriar as informações do planejador de consultas.

Você deve obter um desempenho melhor usando, COUNT(an uniquly indexed field)mas se for muito grande, uma varredura seq é a única maneira de fazer isso.

Se você precisar de números muito rápidos e não tiver medo de consultar o esquema, faça o seguinte

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

Mas não confie nesses valores, pois é apenas um número "estimado" (embora muitas vezes o exato) de tuplas na tabela.

DrColossos
fonte
Eu não acho que isso esteja correto. Não li nada em nenhum lugar, onde COUNT(pk)melhore o desempenho. Eu acho que vai sempre fazer uma seq-scan
vol7ron
1
Sem uma cláusula where, você está correto, uma verificação seq será executada. Com uma cláusula where suficientemente selecionada, o postgresql PODE usar um índice, mas lembre-se de que VOLTARÁ à tabela para verificar a visibilidade das tuplas nas quais está relatando.
Scott Marlowe