Eu tenho tentado COUNT(*)
uma tabela com 150.000 linhas que tem uma chave primária. É ferramenta cerca de 5 minutos, então eu descobri que este é um problema de indexação.
Citando o manual do PostgreSQL :
O REINDEX é semelhante a uma remoção e recriação do índice, pois o conteúdo do índice é reconstruído do zero. No entanto, as considerações de bloqueio são bastante diferentes. REINDEX bloqueia gravações, mas não leituras da tabela pai do índice. Também é necessário um bloqueio exclusivo no índice específico que está sendo processado, o que bloqueará as leituras que tentam usar esse índice (...) O subsequente CREATE INDEX bloqueia gravações, mas não leituras; como o índice não está lá, nenhuma leitura tentará usá-lo, o que significa que não haverá bloqueio, mas as leituras podem ser forçadas a verificações seqüenciais caras.
A partir de sua própria experiência, você pode dizer:
- é
REINDEXING
perigoso? Isso pode prejudicar a consistência dos dados? - Pode demorar muito tempo?
- É uma solução provável para o meu cenário?
Atualizar:
A solução que funcionou para nós foi recriar o mesmo índice com um nome diferente e excluir o índice antigo.
A criação do índice é muito rápida e reduzimos o tamanho do índice de 650 MB para 8 MB. Usar um COUNT(*)
com between
leva apenas 3 segundos.
fonte
COUNT(*)
é a melhor escolha:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.
Não tenho certeza da melhor resposta para você. No entanto, este tópico parece oferecer algumas boas sugestões: n http://postgresql.1045698.n5.nabble.com/count-performance-issue-td2067873.html
Uma observação é que você pode implementar um TRIGGER para manter as contagens de linhas em uma tabela separada (se COUNT (*) fosse chamado com freqüência por seus aplicativos).
Algumas das respostas sugerem que isso é sintomático de um banco de dados que não foi aspirado recentemente o suficiente (sugerindo que o autovacuum esteja desativado no seu servidor ou para esse banco de dados em particular)?
Outra sugestão se parece com:
E alguém identificado como A. Kretschmer observa:
Não. A implementação do índice atual não contém informações sobre a visibilidade da linha na transação atual. Você precisa varrer toda a tabela de dados para obter se a linha atual está visível na transação atual.
... apoiando meu comentário sobre as permissões no nível da linha como uma preocupação de desempenho.
Minha pesquisa também descobriu o WikiVS: MySQL vs. PostgreSQL: COUNT (*) .
Você pode ler os outros resultados que encontrei usando o Google: desempenho do postgresql count (*)
fonte